[Issue 13726] New: Build Phobos and Druntime with stack frames enabled (-gs)
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Wed Nov 12 17:31:25 PST 2014
https://issues.dlang.org/show_bug.cgi?id=13726
Issue ID: 13726
Summary: Build Phobos and Druntime with stack frames enabled
(-gs)
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: enhancement
Priority: P1
Component: Phobos
Assignee: nobody at puremagic.com
Reporter: thecybershadow at gmail.com
Background: enabling stack frames causes the compiler to emit a few extra
prologue/epilogue instructions for each function which save the stack pointer
right near the function return address. This creates a linked list, which, when
traversed, provides information for each function's address in the call stack
(and where within the function it invokes the next function), and the size of
its stack frame.
Stack frames are a good debugging aid and have a minimal impact on performance.
I suggest to build Phobos and Druntime with these enabled.
An example use case where stack frames are useful is debugging
InvalidMemoryOperation errors. These errors are currently difficult to debug.
Consider the following program:
//////////// test.d ////////////
import core.memory;
class C
{
~this() { new ubyte[1024]; }
}
void faulty()
{
foreach (n; 0..1000)
new C();
GC.collect();
}
void main()
{
faulty();
}
////////////////////////////////
This program allocates in a destructor, which is not allowed. When ran, it only
prints core.exception.InvalidMemoryOperationError@(0), because a stack trace is
purposefully not allocated for memory operations (and even if it was, it would
still be incorrect, as seen below).
When the program is launched from a debugger, on Windows, the runtime will
disable its own exception handler, and the program will break on the point
where the InvalidMemoryOperationError is thrown. However, the stack trace will
look as follows:
> KernelBase.dll!_RaiseException at 16() + 0x58 bytes
test.exe!_D2rt3deh9throwImplFC6ObjectZv() + 0x1a bytes
test.exe!_onInvalidMemoryOperationError() + 0xc bytes
test.exe!_gc_malloc() + 0x1e bytes
test.exe!_D2gc3gcx3Gcx11fullcollectMFZk() + 0x617 bytes
test.exe!_D2gc3gcx2GC11fullCollectMFZk() + 0x45 bytes
Because _gc_malloc does not create a stack frame, the stack trace is corrupt -
it incorrectly shows that Gcx.fullcollect invokes gc_malloc. The stack trace
ends abruptly at GC.fullCollect, and does not contain any useful information on
why the problem occurred.
If Phobos and Druntime are rebuilt with -gs, we see the following stack trace
instead:
KernelBase.dll!_RaiseException at 16() + 0x58 bytes
test.exe!_D2rt9deh_win329throwImplFC6ObjectZv() + 0x23 bytes
test.exe!__d_throwc() + 0xc bytes
test.exe!_D2gc2gc2GC12mallocNoSyncMFNbkkKkxC8TypeInfoZPv() + 0x1f bytes
test.exe!_D2gc2gc2GC6mallocMFNbkkPkxC8TypeInfoZPv() + 0x51 bytes
test.exe!_gc_malloc() + 0x21 bytes
test.exe!__d_newclass() + 0x66 bytes
test.exe!_rt_finalize2() + 0xee bytes
test.exe!_D2gc2gc3Gcx11fullcollectMFNbZk() + 0x8c8 bytes
test.exe!_D2gc2gc2GC11fullCollectMFNbZk() + 0x1f bytes
test.exe!_gc_collect() + 0x16 bytes
test.exe!_D4core6memory2GC7collectFNbZv() + 0x8 bytes
> test.exe!test.faulty() Line 13 C
test.exe!D main() Line 17 + 0x5 bytes C
(rest omitted)
We don't see the destructor in the stack trace because of issue 13723. With
issue 13725 fixed, onInvalidMemoryOperationError can be breakpointed instead
(this approach also requires stack frames for a useful stack trace).
--
More information about the Digitalmars-d-bugs
mailing list