I came across a strange behavior with Gambit Scheme on Windows (XP, in this case). I wrote a module to convert C++ std::string types to Gambit char-strings. I wanted to use that in a loadable module. This all works fine on Linux, but I also need to use it on Windows. I'm using MinGW's C++ compiler (g++ version 4.6.2 -- which I also used to compile Gambit). And I'm still on version 4.6.5 of Gambit Scheme.
I've attached a zipped tar file with an example (6 files, including a build.windows script and a build.linux script).
When I load the shared module in gsi on Windows XP, it segfaults in ___garbage_collect(long) -- I believe it was in the call to ___alloc_scmobj. When I load it on Linux it works just fine. The executable built by the scripts on both platforms works just fine.
I would love to know what is causing this. I've spent many hours trying to find the source of the problem, and finally narrowed it down to this.
Any help/explanations/suggestions would be much appreciated.
repleffect
Afficher les réponses par date
Just to start, are you sure that when you return that string, that it remains on the C heap somewhere all until your string_to_SCMOBJ procedure digests it?
I mean, if it's on the stack, then probably it's overwritten by the subsequent C procedure call to string_to_SCMOBJ, which consumes stack space (the unsigned int and ___SCMOBJ in string_to_SCMOBJ should take the first positions of stack space that f1b_hello previously occupied, and thus destroy the structure?).
If it had been a char* constant you had returned instead, I suppose the C compiler would have put it in some separate, reserved area.
Well just a wild guess.
What about adding Lots of debug printf:s in string_to_SCMOBJ as to check that it produces the right thing.
Last, in your type definition (c-define-type string "string" "string_to_SCMOBJ" "SCMOBJ_to_string" #f) you use #f for release function i.e. afaik free()?
That's not the right thing right, you'd want C++' delete or sth..?
Also why is not the string type you use pointered? Please correct me on this one.
Brgds
2012/9/28 REPLeffect repleffect@gmail.com
I came across a strange behavior with Gambit Scheme on Windows (XP, in this case). I wrote a module to convert C++ std::string types to Gambit char-strings. I wanted to use that in a loadable module. This all works fine on Linux, but I also need to use it on Windows. I'm using MinGW's C++ compiler (g++ version 4.6.2 -- which I also used to compile Gambit). And I'm still on version 4.6.5 of Gambit Scheme.
I've attached a zipped tar file with an example (6 files, including a build.windows script and a build.linux script).
When I load the shared module in gsi on Windows XP, it segfaults in ___garbage_collect(long) -- I believe it was in the call to ___alloc_scmobj. When I load it on Linux it works just fine. The executable built by the scripts on both platforms works just fine.
I would love to know what is causing this. I've spent many hours trying to find the source of the problem, and finally narrowed it down to this.
Any help/explanations/suggestions would be much appreciated.
repleffect
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
What inspired you to the particular design of string_to_SCMOBJ (things like ___CTOS_HEAP_OVERFLOW_ERR+arg_num;)?
2012/9/28 Mikael mikael.rcv@gmail.com
Just to start, are you sure that when you return that string, that it remains on the C heap somewhere all until your string_to_SCMOBJ procedure digests it?
I mean, if it's on the stack, then probably it's overwritten by the subsequent C procedure call to string_to_SCMOBJ, which consumes stack space (the unsigned int and ___SCMOBJ in string_to_SCMOBJ should take the first positions of stack space that f1b_hello previously occupied, and thus destroy the structure?).
If it had been a char* constant you had returned instead, I suppose the C compiler would have put it in some separate, reserved area.
Well just a wild guess.
What about adding Lots of debug printf:s in string_to_SCMOBJ as to check that it produces the right thing.
Last, in your type definition (c-define-type string "string" "string_to_SCMOBJ" "SCMOBJ_to_string" #f) you use #f for release function i.e. afaik free()?
That's not the right thing right, you'd want C++' delete or sth..?
Also why is not the string type you use pointered? Please correct me on this one.
Brgds
2012/9/28 REPLeffect repleffect@gmail.com
I came across a strange behavior with Gambit Scheme on Windows (XP, in this case). I wrote a module to convert C++ std::string types to Gambit char-strings. I wanted to use that in a loadable module. This all works fine on Linux, but I also need to use it on Windows. I'm using MinGW's C++ compiler (g++ version 4.6.2 -- which I also used to compile Gambit). And I'm still on version 4.6.5 of Gambit Scheme.
I've attached a zipped tar file with an example (6 files, including a build.windows script and a build.linux script).
When I load the shared module in gsi on Windows XP, it segfaults in ___garbage_collect(long) -- I believe it was in the call to ___alloc_scmobj. When I load it on Linux it works just fine. The executable built by the scripts on both platforms works just fine.
I would love to know what is causing this. I've spent many hours trying to find the source of the problem, and finally narrowed it down to this.
Any help/explanations/suggestions would be much appreciated.
repleffect
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Alas I can claim no haughty inspiration... :-D
The conversion code is pretty much a blatant ripoff of Marc's code for converting from Qt QStrings from the "Guide" source code. You can see it in the lib/guide directory in the Gambit source code (in _guide.scm, guide.cpp, guide .h, etc)...I actually started having the problem when using that same code to convert QStrings. At the time I didn't realize that it was a platform-specific problem, and since it worked fine when statically compiled into an executable, I wondered if it had something to do with some strange issue with dynamic binding and the fact that QStrings are implicitly shared. So I tried to do it with std::string, and lo and behold it has the same problem.
I think the #f in (c-define-type string "string" "string_to_SCMOBJ" "SCMOBJ_to_string" #f) is actually right in this case. That's the way it was in Marc's QString code, and I think it is because the string object is being passed by value, not by a pointer, so I think the cleanup will occur automatically in that case (the QStrings were being passed the same way in the original code).
I already did printf's in the conversion code, and I also rebuilt Gambit with --enable-debug and stepped through what I could. I could never get it to trace throught the ___alloc_scmobj() function on Windows, however (not sure why).
repleffect
On 9/28/12, Mikael mikael.rcv@gmail.com wrote:
What inspired you to the particular design of string_to_SCMOBJ (things like ___CTOS_HEAP_OVERFLOW_ERR+arg_num;)?
2012/9/28 Mikael mikael.rcv@gmail.com
Just to start, are you sure that when you return that string, that it remains on the C heap somewhere all until your string_to_SCMOBJ procedure digests it?
I mean, if it's on the stack, then probably it's overwritten by the subsequent C procedure call to string_to_SCMOBJ, which consumes stack space (the unsigned int and ___SCMOBJ in string_to_SCMOBJ should take the first positions of stack space that f1b_hello previously occupied, and thus destroy the structure?).
If it had been a char* constant you had returned instead, I suppose the C compiler would have put it in some separate, reserved area.
Well just a wild guess.
What about adding Lots of debug printf:s in string_to_SCMOBJ as to check that it produces the right thing.
Last, in your type definition (c-define-type string "string" "string_to_SCMOBJ" "SCMOBJ_to_string" #f) you use #f for release function i.e. afaik free()?
That's not the right thing right, you'd want C++' delete or sth..?
Also why is not the string type you use pointered? Please correct me on this one.
Brgds
2012/9/28 REPLeffect repleffect@gmail.com
I came across a strange behavior with Gambit Scheme on Windows (XP, in this case). I wrote a module to convert C++ std::string types to Gambit char-strings. I wanted to use that in a loadable module. This all works fine on Linux, but I also need to use it on Windows. I'm using MinGW's C++ compiler (g++ version 4.6.2 -- which I also used to compile Gambit). And I'm still on version 4.6.5 of Gambit Scheme.
I've attached a zipped tar file with an example (6 files, including a build.windows script and a build.linux script).
When I load the shared module in gsi on Windows XP, it segfaults in ___garbage_collect(long) -- I believe it was in the call to ___alloc_scmobj. When I load it on Linux it works just fine. The executable built by the scripts on both platforms works just fine.
I would love to know what is causing this. I've spent many hours trying to find the source of the problem, and finally narrowed it down to this.
Any help/explanations/suggestions would be much appreciated.
repleffect
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Well, I have no one to blame for this but myself.
I noticed I was using g++ 4.4.5 on Linux (where the code worked fine). So I decided to try that version on Windows. I downloded a binary distribution of g++ for MinGW (version 4.4.5) and installed it. I rebuilt/reinstalled Gambit with it first, then when I tried to build my sample program I had to take out the -fno-keep-inline-dllexport option (because 4.4.5 didn't support that option). I reran the test (loaded the f2.o1 file from the interpreter), and it worked like a charm!
I started to think it must be a problem with g++ 4.6.2 (at least this particular MinGW build of it). But I had remembered that it was *I* who had suggested adding the -fno-keep-inline-dllexport option to the build for MinGW (back in February of this year). I don't even remember where I saw the suggestion, but it had to do with things you could do when the compiler was running out of memory.
Then I noticed that in one of my later posts, I'd said I was able to compile just fine *without* the -fno-keep-inline-dllexport option.
I could hear myself saying "Oh, I wonder if that option could be causing the problem in the first place?" I was building a loadable library, and I was also building Gambit with --enable-shared, so it seemed possible.
With that in mind, I tried going back to g++ 4.6.2, and taking the -fno-keep-inline-dllexport option out of the Gambit build and of my test application's build.
Rebuilt, reinstalled, reran the test -- BINGO! Works fine on 4.6.2 without that option.
So ... um ... Marc, I'd like to suggest that you remove the -fno-keep-inline-dllexport option from the build on Windows which I stupidly suggested you add last February :-D
There's a song by the group "Casting Crowns" called "My Own Worst Enemy" (the author is referring to himself).
Tonight I kind of feel that way! :-D
On 9/28/12, REPLeffect repleffect@gmail.com wrote:
Alas I can claim no haughty inspiration... :-D
The conversion code is pretty much a blatant ripoff of Marc's code for converting from Qt QStrings from the "Guide" source code. You can see it in the lib/guide directory in the Gambit source code (in _guide.scm, guide.cpp, guide .h, etc)...I actually started having the problem when using that same code to convert QStrings. At the time I didn't realize that it was a platform-specific problem, and since it worked fine when statically compiled into an executable, I wondered if it had something to do with some strange issue with dynamic binding and the fact that QStrings are implicitly shared. So I tried to do it with std::string, and lo and behold it has the same problem.
I think the #f in (c-define-type string "string" "string_to_SCMOBJ" "SCMOBJ_to_string" #f) is actually right in this case. That's the way it was in Marc's QString code, and I think it is because the string object is being passed by value, not by a pointer, so I think the cleanup will occur automatically in that case (the QStrings were being passed the same way in the original code).
I already did printf's in the conversion code, and I also rebuilt Gambit with --enable-debug and stepped through what I could. I could never get it to trace throught the ___alloc_scmobj() function on Windows, however (not sure why).
repleffect
On 9/28/12, Mikael mikael.rcv@gmail.com wrote:
What inspired you to the particular design of string_to_SCMOBJ (things like ___CTOS_HEAP_OVERFLOW_ERR+arg_num;)?
2012/9/28 Mikael mikael.rcv@gmail.com
Just to start, are you sure that when you return that string, that it remains on the C heap somewhere all until your string_to_SCMOBJ procedure digests it?
I mean, if it's on the stack, then probably it's overwritten by the subsequent C procedure call to string_to_SCMOBJ, which consumes stack space (the unsigned int and ___SCMOBJ in string_to_SCMOBJ should take the first positions of stack space that f1b_hello previously occupied, and thus destroy the structure?).
If it had been a char* constant you had returned instead, I suppose the C compiler would have put it in some separate, reserved area.
Well just a wild guess.
What about adding Lots of debug printf:s in string_to_SCMOBJ as to check that it produces the right thing.
Last, in your type definition (c-define-type string "string" "string_to_SCMOBJ" "SCMOBJ_to_string" #f) you use #f for release function i.e. afaik free()?
That's not the right thing right, you'd want C++' delete or sth..?
Also why is not the string type you use pointered? Please correct me on this one.
Brgds
2012/9/28 REPLeffect repleffect@gmail.com
I came across a strange behavior with Gambit Scheme on Windows (XP, in this case). I wrote a module to convert C++ std::string types to Gambit char-strings. I wanted to use that in a loadable module. This all works fine on Linux, but I also need to use it on Windows. I'm using MinGW's C++ compiler (g++ version 4.6.2 -- which I also used to compile Gambit). And I'm still on version 4.6.5 of Gambit Scheme.
I've attached a zipped tar file with an example (6 files, including a build.windows script and a build.linux script).
When I load the shared module in gsi on Windows XP, it segfaults in ___garbage_collect(long) -- I believe it was in the call to ___alloc_scmobj. When I load it on Linux it works just fine. The executable built by the scripts on both platforms works just fine.
I would love to know what is causing this. I've spent many hours trying to find the source of the problem, and finally narrowed it down to this.
Any help/explanations/suggestions would be much appreciated.
repleffect
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
For the sake of completeness, I thought I would update this again.
Turns out that the -fno-keep-inline-dllexport is necessary to get Qt to compile under MinGW's 4.6.2 g++ compiler. Evidently all of those inline dllexport function attribute definitions cause serious object bloat and cause the compiler to run out of memory. Here's a quote from the gcc docs (section 6.30 "Declaring Attributes of Functions"):
"In previous versions of GCC, the dllexport attribute was ignored for inlined functions, unless the -fkeep-inline-functions flag had been used. The default behaviour now is to emit all dllexported inline functions; however, this can cause object file-size bloat, in which case the old behaviour can be restored by using -fno-keep-inline-dllexport"
I find it interesting that the old compiler (4.4.5) does not cause the problem I experienced, but yet adding the option that is supposed to restore the old compiler's behavior for the new compiler (4.6.2) *does* cause the problem.
I was going to rebuild Qt (currently using 4.7.4) to take out the -fno-keep-inline-dllexport option, in case linking against Qt DLLs with that option might cause the same problem I had in my test program (which was *not* linked with Qt's DLLs). However, Qt won't compile successfully with g++ 4.6.2 from MinGW without that option.
I haven't yet tried to build an loadable library which is linked with Qt's DLLs against the Gambit library which was compiled without "-fno-keep-inline-dllexport". I kind of suspect that this scenario will work, since the problem seemed to be with Gambit's library being compiled that way. At the moment I'm building Qt *with* -fno-keep-inline-dllexport just to get it back the way it was. I'll try to report back later on what I discover about a Qt-linked loadable library.
I would be interested to know why the -fno-keep-inline-dllexport option causes a problem for Gambit. I'm sure I don't have enough understanding of the inter-workings of Gambit to figure it out myself, but I'd be willing to try to help as much as I can to help determine the cause.
REPLeffect
Yup. That did it. Even went back to the original code for converting from QStrings and all is well, just so long as I leave out the -fno-keep-inline-dllexport from Gambit's compile and the loadable library's compile. Having that option in the Qt build doesn't seem to matter.
On 9/29/12, REPLeffect repleffect@gmail.com wrote:
For the sake of completeness, I thought I would update this again.
Turns out that the -fno-keep-inline-dllexport is necessary to get Qt to compile under MinGW's 4.6.2 g++ compiler. Evidently all of those inline dllexport function attribute definitions cause serious object bloat and cause the compiler to run out of memory. Here's a quote from the gcc docs (section 6.30 "Declaring Attributes of Functions"):
"In previous versions of GCC, the dllexport attribute was ignored for inlined functions, unless the -fkeep-inline-functions flag had been used. The default behaviour now is to emit all dllexported inline functions; however, this can cause object file-size bloat, in which case the old behaviour can be restored by using -fno-keep-inline-dllexport"
I find it interesting that the old compiler (4.4.5) does not cause the problem I experienced, but yet adding the option that is supposed to restore the old compiler's behavior for the new compiler (4.6.2) *does* cause the problem.
I was going to rebuild Qt (currently using 4.7.4) to take out the -fno-keep-inline-dllexport option, in case linking against Qt DLLs with that option might cause the same problem I had in my test program (which was *not* linked with Qt's DLLs). However, Qt won't compile successfully with g++ 4.6.2 from MinGW without that option.
I haven't yet tried to build an loadable library which is linked with Qt's DLLs against the Gambit library which was compiled without "-fno-keep-inline-dllexport". I kind of suspect that this scenario will work, since the problem seemed to be with Gambit's library being compiled that way. At the moment I'm building Qt *with* -fno-keep-inline-dllexport just to get it back the way it was. I'll try to report back later on what I discover about a Qt-linked loadable library.
I would be interested to know why the -fno-keep-inline-dllexport option causes a problem for Gambit. I'm sure I don't have enough understanding of the inter-workings of Gambit to figure it out myself, but I'd be willing to try to help as much as I can to help determine the cause.
REPLeffect