Throwing InvalidMemoryOperationError

Adam D. Ruppe via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 4 10:41:45 PDT 2015


On Thursday, 4 June 2015 at 16:05:37 UTC, Etienne wrote:
> Why not just let it fail with an access violation of some sort?

You can do this at least with a filthy hack. Add this to your 
file with main():

extern(C) void onInvalidMemoryOperationError(void*) {
    asm { int 3; }
}


Then recompile your program.

class Fail {
         ~this() { auto a = new int; }
}
/*
extern(C) void onInvalidMemoryOperationError(void*) {
    asm { int 3; }
}
*/
void main() {
         auto fail = new Fail();
}


Before:

core.exception.InvalidMemoryOperationError@(0)

After:

Trace/breakpoint trap



`int 3;` is x86/x86_64 talk for "please invoke the debugger" and 
the extern(C) onInvalidMemoryOperationError is what the GC calls 
to throw that exception.

Since the function is in the druntime.lib file though.... you can 
easily override it by simply providing a replacement file in your 
main application. The linker prefers versions of functions from 
.o files over .lib files.

(This also works on Windows btw, I'm just using the linux terms 
cuz that's what I'm on right now)



So now the magic comes if we run the program in gdb:

$ dmd b.d -g

$ gdb b
(gdb) r

Program received signal SIGTRAP, Trace/breakpoint trap.
0x000000000041d0c5 in onInvalidMemoryOperationError ()
=> 0x000000000041d0c5 <onInvalidMemoryOperationError+13>:       
c9      leave

(gdb) where
#0  onInvalidMemoryOperationError (
     _param_0=0x6446a0 <gc.gc.GC.mutexStorage()+16>) at b.d:7
#1  0x0000000000425dfc in gc.gc.GC.malloc() ()
#2  0x0000000000421525 in gc_qalloc ()
#3  0x000000000041e8e1 in _d_newitemT ()
#4  0x000000000041d0b3 in b.Fail.__dtor() (this=0x7ffff7eb8000) 
at b.d:2
#5  0x0000000000435878 in rt_finalize2 ()
#6  0x000000000042d016 in rt_finalizeFromGC ()
#7  0x0000000000429930 in gc.gc.Gcx.sweep() ()
#8  0x000000000042a04b in gc.gc.Gcx.fullcollect() ()
#9  0x000000000042bed9 in gc_term ()
#10 0x0000000000421a9b in rt_term ()
#11 0x000000000041e73e in rt.dmain2._d_run_main() ()
#12 0x000000000041e6ca in rt.dmain2._d_run_main() ()
#13 0x000000000041e644 in _d_run_main ()
#14 0x000000000041d115 in main ()



Line #4 there is the winner! b.d, line 2, my destructor 
allocation :)


More information about the Digitalmars-d mailing list