Re: How to get call stack for InvalidMemoryOperationError while doing unittest?

2021-01-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/13/21 1:22 PM, apz28 wrote:
core.exception.InvalidMemoryOperationError@src\core\exception.d(647): 
Invalid memory operation


I've struggled with this as well. It doesn't even tell you the original 
usage point that causes the exception.


I believe stack traces are disabled from printing on this because of the 
fact that it needs some memory to print the trace or walk the trace 
(this is fuzzy, I think it might not need memory, but I can't remember 
exactly).


You can override the handling of memory errors by defining it yourself:

extern(C) void onInvalidMemoryOperationError(void *pretend_sideeffect = 
null) @trusted pure nothrow @nogc

{
   // try to print stack trace here yourself...
}

A very *very* common reason this is triggered is because a GC destructor 
is trying to allocate memory (this is not allowed during GC cleanup). 
But without knowing the trace, it's really hard to find it.


-Steve


How to get call stack for InvalidMemoryOperationError while doing unittest?

2021-01-13 Thread apz28 via Digitalmars-d-learn

core.exception.InvalidMemoryOperationError@src\core\exception.d(647): Invalid 
memory operation

reference D runtime unittest executor codes
try
{
fp();
++results.passed;
}
catch ( Throwable e )
{
import core.stdc.stdio;
printf("%.*s(%llu): [unittest] %.*s\n",
cast(int) e.file.length, e.file.ptr, cast(ulong) 
e.line,

cast(int) e.message.length, e.message.ptr);

if ( typeid(e) == typeid(AssertError) )
{
// Crude heuristic to figure whether the 
assertion originates in

// the unittested module. TODO: improve.
auto moduleName = m.name;
if (moduleName.length && e.file.length > 
moduleName.length
&& e.file[0 .. moduleName.length] == 
moduleName)

{
// Exception originates in the same module, 
don't print

// the stack trace.
// TODO: omit stack trace only if assert was 
thrown

// directly by the unittest.
continue;
}
}
// TODO: perhaps indent all of this stuff.
_d_print_throwable(e);
}