digitalmars.D - How to tell if the GC is running?
- Tomer Filiba (33/33) Apr 06 2014 I'm writing a logger/tracer that emits a line for every function
- safety0ff (4/4) Apr 06 2014 Please post more of the stack trace, it looks like you're
- Tomer Filiba (5/9) Apr 06 2014 Yes, I know I'm allocating while the GC is collecting. I'm asking
- Etienne (11/19) Apr 06 2014 If the GC is running you get a stack trace with fullcollect() like this:
- Tomer Filiba (5/32) Apr 08 2014 Etienne: I got a SEGFAULT when the runtime was trying to throw
- Rainer Schuetze (24/31) Apr 08 2014 If you don't use explicite or scoped destruction, all class object
I'm writing a logger/tracer that emits a line for every function entry/exit. It naturally makes use of the GC, as it manipulates strings (and calls to!string on arguments, etc). Traced functions may be called normally, but sometimes they are called from a destructor (during a collection). When the latter happens, it gets to my tracer's code, which tries to allocate memory, and dies with a SEGFAULT. It seems that it tried to raise an exception but failed: Program received signal SIGSEGV, Segmentation fault. 0x00000000007f406d in _d_throwc () (gdb) bt std.array.__T9replicateTAyaZ.replicate() (n=2, s=...) at /usr/include/dmd/phobos/std/array.d:1313 foo.runtime.tracing.__T9enterFuncTkZ.enterFunc() (_param_1=0, funcName=...) at ... ... First of all, the SEGFAULT seems to be a bug in the GC itself which probably deserves a ticket. I'd settle with simply disabling my tracer during GC, but there doesn't seem to be any way to tell if I'm in a collection or not. This is what I'm after: https://github.com/D-Programming-Language/druntime/blob/master/src/gc/gc.d#L440 Any help would be appreciated. -tomer
Apr 06 2014
Please post more of the stack trace, it looks like you're allocating while it is running the destructors / finalization https://d.puremagic.com/issues/show_bug.cgi?id=11408
Apr 06 2014
On Sunday, 6 April 2014 at 16:34:02 UTC, safety0ff wrote:Please post more of the stack trace, it looks like you're allocating while it is running the destructors / finalization https://d.puremagic.com/issues/show_bug.cgi?id=11408Yes, I know I'm allocating while the GC is collecting. I'm asking how to avoid this situation -- is there some way to tell that the GC is running? -tomer
Apr 06 2014
On 2014-04-06 5:20 PM, Tomer Filiba wrote:On Sunday, 6 April 2014 at 16:34:02 UTC, safety0ff wrote:If the GC is running you get a stack trace with fullcollect() like this: cache-d_d.exe!gc gc Gcx mark(void * this, void * nRecurse, int ptop) Line 2266 C++ cache-d_d.exe!gc gc Gcx mark(void * this, void * ptop) Line 2249 C++ cache-d_d.exe!gc gc Gcx fullcollect() Line 2454 C++ cache-d_d.exe!gc gc GC mallocNoSync(unsigned int this, unsigned int alloc_size, unsigned int * alloc_size) Line 458 C++ cache-d_d.exe!gc gc GC malloc(unsigned int this, unsigned int alloc_size, unsigned int * bits) Line 413 C++Please post more of the stack trace, it looks like you're allocating https://d.puremagic.com/issues/show_bug.cgi?id=11408Yes, I know I'm allocating while the GC is collecting. I'm asking how to avoid this situation -- is there some way to tell that the GC is running? -tomer
Apr 06 2014
Etienne: I got a SEGFAULT when the runtime was trying to throw the exception. I can't really catch that. Is there some predicate I can use before I'm allocating memory? -tomer On Sunday, 6 April 2014 at 23:20:24 UTC, Etienne wrote:On 2014-04-06 5:20 PM, Tomer Filiba wrote:On Sunday, 6 April 2014 at 16:34:02 UTC, safety0ff wrote:If the GC is running you get a stack trace with fullcollect() like this: cache-d_d.exe!gc gc Gcx mark(void * this, void * nRecurse, int ptop) Line 2266 C++ cache-d_d.exe!gc gc Gcx mark(void * this, void * ptop) Line 2249 C++ cache-d_d.exe!gc gc Gcx fullcollect() Line 2454 C++ cache-d_d.exe!gc gc GC mallocNoSync(unsigned int this, unsigned int alloc_size, unsigned int * alloc_size) Line 458 C++ cache-d_d.exe!gc gc GC malloc(unsigned int this, unsigned int alloc_size, unsigned int * bits) Line 413 C++Please post more of the stack trace, it looks like you're allocating https://d.puremagic.com/issues/show_bug.cgi?id=11408Yes, I know I'm allocating while the GC is collecting. I'm asking how to avoid this situation -- is there some way to tell that the GC is running? -tomer
Apr 08 2014
On 06.04.2014 23:20, Tomer Filiba wrote:On Sunday, 6 April 2014 at 16:34:02 UTC, safety0ff wrote:If you don't use explicite or scoped destruction, all class object destructors are called from the GC finalization, so you might just call a different function from class destructors. For structs, they are (currently) not finalized if heap allocated, but their destructor is called for struct fields of a class. To implement a check: this is very implementation specific, but the GC has an internal variable "running" that is set during collection. The problem is how to read this variable. This involves accessing the private global _gc in gc.proxy. If you are ok with modifying the runtime, add a method to gc.proxy like this: bool gc_iscollecting() { return _gc.gcx.running; } (you can make this a template function to avoid having to rebuild the library). The even hackier solution is to use the mangled name of the private variable somewhere in your code: import gc.gc; extern(C) extern __gshared gc.gc.GC _D2gc5proxy3_gcC2gc2gc2GC; bool gc_iscollecting() { return _D2gc5proxy3_gcC2gc2gc2GC.gcx.running; } (Depending on the architecture/platform, you might have to remove the leading underscore from that identifier). For both approaches you will have to add druntime/src to your import paths, as the gc modules are not part of the modules in the druntime/import folder.Please post more of the stack trace, it looks like you're allocating https://d.puremagic.com/issues/show_bug.cgi?id=11408Yes, I know I'm allocating while the GC is collecting. I'm asking how to avoid this situation -- is there some way to tell that the GC is running?
Apr 08 2014