Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
August 21, 2005 Using D from C | ||||
---|---|---|---|---|
| ||||
Is there some function to initialize the D, like JvCreateJavaVM in GCJ CNI? 8<--- Test.d ------->8 class DeeTest { void test(){ printf( "D" ); } } extern( C ){ void testFunction(){ DeeTest deeTest = new DeeTest(); deeTest.test(); } } 8<--- main.c ------->8 void testFunction(); int main( char** argv, int argc ){ testFunction(); return 0; } 8<--- Problem ------->8 (gdb) run Starting program: /home/Glim/dee/c_test.exe Program received signal SIGSEGV, Segmentation fault. 0x0040311c in _d_newclass () (gdb) bt #0 0x0040311c in _d_newclass () #1 0x004010c1 in testFunction () at ru/glim/deetest/Test.d:8 #2 0x0040107f in main (argv=0x1, argc=4726336) at main.c:3 (gdb) |
August 24, 2005 Re: Using D from C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artem Gr Attachments: | Artem Gr schrieb: > > Is there some function to initialize the D, > like JvCreateJavaVM in GCJ CNI? Have a look at the code below. Thomas ========== dmd -c phobosc.d some.d gcc -o main main.c some.o phobosc.o -lphobos -lpthread -lm ./main =====phobosc.d===== /* enable access to D code from C Copyright (C) 2005 Thomas Kuehne <thomas@kuehne.cn> Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, definition, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, definition, disclaimer, and this list of conditions in documentation and/or other materials provided with the distribution. 3. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. */ module kuehne.phobosc; private{ import std.c.stdio; import std.c.stdlib; extern (C) void _STI_monitor_staticctor(); extern (C) void _STD_monitor_staticdtor(); extern (C) void _STI_critical_init(); extern (C) void _STD_critical_term(); extern (C) void gc_init(); extern (C) void gc_term(); extern (C) void _minit(); extern (C) void _moduleCtor(); extern (C) void _moduleDtor(); extern (C) void _moduleUnitTests(); // sometimes required by the linker extern(C) void* _deh_beg; extern(C) void *_deh_end; // protect D memory against GC size_t[void*] memoryGuard; Object sync; // cope with multiple inits & unloads size_t loadCount; } /* call before the use of any D code * multiple calls */ public extern(C) int loadPhobos(){ if(loadCount==0){ version (linux){ _STI_monitor_staticctor(); _STI_critical_init(); gc_init(); } version (Win32){ gc_init(); _minit(); } try{ _moduleCtor(); _moduleUnitTests(); sync = new Object(); }catch(Object o){ fprintf(stderr, "Error: %.*s", o.toString()); return 0; } } loadCount++; return 0; } public extern(C) void unloadPhobos(){ if(loadCount==1){ _moduleDtor(); gc_term(); version (linux){ _STD_critical_term(); _STD_monitor_staticdtor(); } } if(loadCount>0){ loadCount--; } } /* protect memory allocated by D's GC to be collected * while storing the memory in some C code */ public extern(C) void markMemoryFromD(void* ptr){ synchronized(sync){ if(ptr in memoryGuard){ memoryGuard[ptr]+=1; }else{ memoryGuard[ptr]=1; } } } /* remove GC collection guard if no further mark is set */ public extern(C) void unmarkMemoryFromD(void* ptr){ synchronized(sync){ if(ptr in memoryGuard){ if(--memoryGuard[ptr] == 0){ memoryGuard.remove(ptr); } } } } /* remove GC collection guard */ public extern(C) void forceUnmarkMemoryFromD(void* ptr){ if(ptr in memoryGuard){ memoryGuard.remove(ptr); } } =====phobosc.h===== #ifndef PHOBOSC_H #define PHOBOSC_H int loadPhobos(); void unloadPhobos(); void markMemoryFromD(void* ptr); void unmarkMemoryFromD(void* ptr); void forceUnmarkMemoryFromD(void* ptr); #endif =====main.c===== #include "phobosc.h" extern void* _D4some5test1FZC1c6Sample(); // D linkage extern void* test2(void*); // C linkage int main(){ loadPhobos(); void* a = _D1c5test1FZC1c6Sample(); markMemoryFromD(a); void* b = _D1c5test1FZC1c6Sample(); markMemoryFromD(b); test2(a); test2(a); test2(b); test2(a); unmarkMemoryFromD(a); unmarkMemoryFromD(b); unloadPhobos(); return 0; } =====some.d==== module some; import std.stdio; class Sample : Object{ int id; static int idCounter; this(){ id=(idCounter++); } } Sample test1(){ Sample o = new Sample; writef("test1 id:%s\n", o.id); return o; } extern(C) void test2(Sample o){ writef("test2 id:%s\n", o.id); } |
August 31, 2005 Re: Using D from C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas Kühne | Thomas Kühne escribió: > private{ > import std.c.stdio; > import std.c.stdlib; > > extern (C) void _STI_monitor_staticctor(); > extern (C) void _STD_monitor_staticdtor(); > extern (C) void _STI_critical_init(); > extern (C) void _STD_critical_term(); > extern (C) void gc_init(); > extern (C) void gc_term(); > extern (C) void _minit(); > extern (C) void _moduleCtor(); > extern (C) void _moduleDtor(); > extern (C) void _moduleUnitTests(); > > // sometimes required by the linker > extern(C) void* _deh_beg; > extern(C) void *_deh_end; > > // protect D memory against GC > size_t[void*] memoryGuard; > Object sync; > > // cope with multiple inits & unloads > size_t loadCount; > } > > /* call before the use of any D code > * multiple calls > */ > public extern(C) int loadPhobos(){ > if(loadCount==0){ > version (linux){ > _STI_monitor_staticctor(); > _STI_critical_init(); > gc_init(); > } > > version (Win32){ > gc_init(); > _minit(); > } > > try{ > _moduleCtor(); > _moduleUnitTests(); > sync = new Object(); > }catch(Object o){ > fprintf(stderr, "Error: %.*s", o.toString()); > return 0; > } > } > > loadCount++; > > return 0; > } > > public extern(C) void unloadPhobos(){ > if(loadCount==1){ > _moduleDtor(); > gc_term(); > version (linux){ > > _STD_critical_term(); > _STD_monitor_staticdtor(); > } > > } > > if(loadCount>0){ > loadCount--; > } > } > I'm trying to do this but from C but Pascal (using FreePascal 2.0.0) on Mac OS X 10.3.9, but I get "Bus error" all the time. gdb shows this: Program received signal EXC_BAD_ACCESS, Could not access memory. 0x9001f898 in malloc_create_zone () (gdb) bt #0 0x9001f898 in malloc_create_zone () #1 0x9002c424 in _malloc_initialize () #2 0x90001a00 in malloc () #3 0x000042e8 in gc_init () at ../../../gcc-3.4.3/libphobos/internal/gc/gc.d:106 #4 0x00001958 in Dinit () at d.d:32 #5 0x8fe1a278 in __dyld__dyld_start () Any ideas? -- Carlos Santander Bernal |
August 31, 2005 Re: Using D from C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander Attachments: | Carlos Santander schrieb: [snip] > I'm trying to do this but from C but Pascal (using FreePascal 2.0.0) on Mac OS X 10.3.9, but I get "Bus error" all the time. gdb shows this: > > Program received signal EXC_BAD_ACCESS, Could not access memory. > 0x9001f898 in malloc_create_zone () > (gdb) bt > #0 0x9001f898 in malloc_create_zone () > #1 0x9002c424 in _malloc_initialize () > #2 0x90001a00 in malloc () > #3 0x000042e8 in gc_init () at > ../../../gcc-3.4.3/libphobos/internal/gc/gc.d:106 > #4 0x00001958 in Dinit () at d.d:32 > #5 0x8fe1a278 in __dyld__dyld_start () > > Any ideas? Please try the code below - it seems to work on Linux and Windows. If it isn't working properly compile with "-debug=StdioInit" and/or execute the sniplet below BEFORE calling loadPhobos. Thomas - -------------------------------------------- private import gcc.gc_guess_stack; // // argv from C's: int main(int argc, char **argv) // extern(C) setStackOriginGuess(char **argv){ stackOriginGuess = &argv; } - -------------------------------------------- /* enable access to D code from C Copyright (C) 2005 Thomas Kuehne <thomas@kuehne.cn> Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, definition, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, definition, disclaimer, and this list of conditions in documentation and/or other materials provided with the distribution. 3. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. */ module kuehne.phobosc; private{ // only required for error reporting import std.c.stdio; import std.c.stdlib; // cope with DMD's and GDC's version war version(Unix){}else version(linux){version=Unix;} extern (C) void gc_init(); extern (C) void gc_term(); extern (C) void _moduleCtor(); extern (C) void _moduleDtor(); extern (C) void _moduleUnitTests(); version(Unix){ extern (C) void _STI_monitor_staticctor(); extern (C) void _STD_monitor_staticdtor(); extern (C) void _STI_critical_init(); extern (C) void _STD_critical_term(); } version(Windows){ extern (C) void _minit(); } // sometimes required by the linker extern(C) void* _deh_beg; extern(C) void *_deh_end; // protect D memory against GC size_t[void*] memoryGuard; Object sync; debug(StdioInit){ extern(C) void _d_gnu_cbridge_init_stdio(); } // cope with multiple inits & unload size_t loadCount; } /** call before the use of any D code multiple calls are harmle returns 0 for succe */ public extern(C) int loadPhobos(){ if(loadCount==0){ version (Windows){ gc_init(); _minit(); }else version(Unix){ _STI_monitor_staticctor(); _STI_critical_init(); gc_init(); }else{ pragma(msg, "missing GC init"); static assert(0); } debug(StdioInit){ _d_gnu_cbridge_init_stdio(); } try{ _moduleCtor(); _moduleUnitTests(); sync = new Object(); }catch(Object o){ fprintf(stderr, "Error: %.*s", o.toString()); return 1; } } loadCount++; return 0; } /** don't use any D code or GCed memory after calling thi remember to call unloadPhobos as many times as loadPhobos succeeded */ public extern(C) void unloadPhobos(){ if(loadCount==1){ _moduleDtor(); gc_term(); version(Unix){ _STD_critical_term(); _STD_monitor_staticdtor(); } } if(loadCount>0){ loadCount--; } } /** protect memory allocated by D's GC to be collected while storing the memory in some C code */ public extern(C) void markMemoryFromD(void* ptr){ synchronized(sync){ size_t* count = ptr in memoryGuard; if(count){ (*count)++; }else{ memoryGuard[ptr]=1; } } } /** remove GC collection guard if no further mark is set */ public extern(C) void unmarkMemoryFromD(void* ptr){ synchronized(sync){ size_t* count = ptr in memoryGuard; if(count && (--(*count) == 0)){ memoryGuard.remove(ptr); } } } /** remove GC collection guard */ public extern(C) void forceUnmarkMemoryFromD(void* ptr){ if(ptr in memoryGuard){ memoryGuard.remove(ptr); } } |
September 01, 2005 Re: Using D from C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas Kühne | Thomas Kühne escribió: > Please try the code below - it seems to work on Linux and Windows. > I get exactly the same as before. > If it isn't working properly compile with "-debug=StdioInit" and/or With this, I get: /usr/bin/ld: Undefined symbols: __d_gnu_cbridge_init_stdio > execute the sniplet below BEFORE calling > loadPhobos. > > Thomas > > - -------------------------------------------- > private import gcc.gc_guess_stack; > > // > // argv from C's: int main(int argc, char **argv) > // > extern(C) setStackOriginGuess(char **argv){ > stackOriginGuess = &argv; > } > - -------------------------------------------- > I suppose this is the sniplet you were referring to. With this, I get: /usr/bin/ld: Undefined symbols: __D3gcc14gc_guess_stack16stackOriginGuessPv -- Carlos Santander Bernal |
September 02, 2005 Re: Using D from C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander Attachments: | Carlos Santander schrieb: > Thomas Kühne escribió: > >> Please try the code below - it seems to work on Linux and Windows. >> > > I get exactly the same as before. [snip] I can think of three (more or less) likely possibilities: 1) your ram is messed up 2) malloc is buggy 3) someone is messing up the memory Let's find out who is at fault: - ----- gdb ./application [some license stuff] (gdb) set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib (gdb) r [some crash] (gdb) bt - ----- further information: http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/libgmalloc.3.html Thomas |
September 03, 2005 Re: Using D from C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas Kühne | Thomas Kühne escribió: > > [snip] > > I can think of three (more or less) likely possibilities: > 1) your ram is messed up > 2) malloc is buggy > 3) someone is messing up the memory > > Let's find out who is at fault: > > - ----- > > gdb ./application > [some license stuff] > (gdb) set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib > (gdb) r > [some crash] > (gdb) bt > > - ----- > > further information: > http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/libgmalloc.3.html > > Thomas I'm sorry, but I don't understand what you're trying to say here. I entered that "set env ..." command but the result was exactly the same. I'm lost by this post... -- Carlos Santander Bernal |
September 03, 2005 Re: Using D from C | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander Attachments: | Carlos Santander schrieb: > Thomas Kühne escribió: > >> >> [snip] >> >> I can think of three (more or less) likely possibilities: >> 1) your ram is messed up >> 2) malloc is buggy >> 3) someone is messing up the memory >> >> Let's find out who is at fault: >> >> - ----- >> >> gdb ./application >> [some license stuff] >> (gdb) set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib >> (gdb) r >> [some crash] >> (gdb) bt >> >> - ----- >> >> further information: http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/libgmalloc.3.html >> >> >> Thomas > > > I'm sorry, but I don't understand what you're trying to say here. I entered that "set env ..." command but the result was exactly the same. I'm lost by this post... > First of all I assume: neither your RAM nor your kernel are broken Ok, let's have a look at the backtrace: > Program received signal EXC_BAD_ACCESS, Could not access memory. > 0x9001f898 in malloc_create_zone () > (gdb) bt > #0 0x9001f898 in malloc_create_zone () > #1 0x9002c424 in _malloc_initialize () > #2 0x90001a00 in malloc () > #3 0x000042e8 in gc_init () at > ../../../gcc-3.4.3/libphobos/internal/gc/gc.d:106 > #4 0x00001958 in Dinit () at d.d:32 > #5 0x8fe1a278 in __dyld__dyld_start () Etnries #2 to #0 indicate, that the system call "malloc" exploded. Neither malloc_create_zone nor _malloc_initialize seem to be properly documented. As a side note http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/malloc.3.html states that malloc should return a NULL pointer if there were any error, but we aren't even getting to the return stage. So what does OpenDarwin do? http://darwinsource.opendarwin.org/10.2/Libc-262/gen/malloc.c > void *malloc(size_t size) { > return malloc_zone_malloc(inline_malloc_default_zone(), size); > } > static inline malloc_zone_t *inline_malloc_default_zone(void) { > if (!malloc_num_zones) _malloc_initialize(); > return malloc_zones[0]; > } > static void _malloc_initialize(void) { > // guaranteed to be called only once > (void)malloc_create_zone(0, 0); > malloc_set_zone_name(malloc_zones[0], "DefaultMallocZone"); > LOCK_INIT(_malloc_lock); > } > malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned > flags) { > malloc_zone_t *zone; > if (!malloc_num_zones) { > char **env = * _NSGetEnviron(); > char **p; > char *c; > /* Given that all environment variables start with "Malloc" we > optimize by scanning quickly first the environment, therefore > avoiding repeated calls to getenv() */ > for (p = env; (c = *p) != NULL; ++p) { > if (!strncmp(c, "Malloc", 6)) { > set_flags_from_environment(); > break; > } > } > > } > zone = create_scalable_zone(start_size, malloc_debug_flags); > malloc_zone_register(zone); > return zone; > } Either the following line is the reason or somewhere code before gc.d:106 messed up malloc_zones or malloc_num_zones (e.g by writing past the allocated memory). char **env = * _NSGetEnviron(); Thomas |
Copyright © 1999-2021 by the D Language Foundation