Invalid memory operation during allocation with `new`

Adam D. Ruppe destructionator at gmail.com
Mon Jan 13 20:30:33 UTC 2020


On Monday, 13 January 2020 at 09:34:42 UTC, Per Nordlöw wrote:
> Without finding any potential problems. Any other suggestions 
> on how to trace this problem?

Run the program in a debugger with the `--DRT-trapExceptions=0` 
argument to the program with certain versions of druntime, or set 
a breakpoint at that function.

On Linux for example, I made a program "pain" that deliberately 
crashes:

-----------------

$ gdb pain
GNU gdb (GDB) 8.3.1
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-slackware-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
     <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from pain...
(gdb) break onInvalidMemoryOperationError
Breakpoint 1 at 0x4614f8
(gdb) r
Starting program: /home/me/test/pain
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, 0x00000000004614f8 in onInvalidMemoryOperationError 
()
(gdb) where
#0  0x00000000004614f8 in onInvalidMemoryOperationError ()
#1  0x000000000045da4b in 
_D2gc4impl12conservativeQw14ConservativeGC__T9runLockedS_DQCeQCeQCcQCnQBs12mallocNoSyncMFNbmkKmxC8TypeInfoZPvS_DQEgQEgQEeQEp10mallocTimelS_DQFiQFiQFgQFr10numMallocslTmTkTmTxQCzZQFcMFNbKmKkKmKxQDsZQDl ()
#2  0x0000000000455a6e in 
_D2gc4impl12conservativeQw14ConservativeGC6mallocMFNbmkxC8TypeInfoZPv ()
#3  0x000000000043546b in gc_malloc ()
#4  0x000000000043160b in _d_newclass ()
#5  0x000000000042f65c in pain.Foo.~this() (this=0x7ffff7af1000) 
at pain.d:3
#6  0x000000000043671c in rt_finalize2 ()
#7  0x0000000000460647 in rt_finalizeFromGC ()
#8  0x0000000000459790 in 
_D2gc4impl12conservativeQw3Gcx5sweepMFNbZm ()
#9  0x000000000045a202 in 
_D2gc4impl12conservativeQw3Gcx11fullcollectMFNbbZm ()
#10 0x000000000045e408 in 
_D2gc4impl12conservativeQw14ConservativeGC__T9runLockedS_DQCeQCeQCcQCnQBs18fullCollectNoStackMFNbZ2goFNbPSQEaQEaQDyQEj3GcxZmTQvZQDfMFNbKQBgZm ()
#11 0x0000000000456f38 in 
_D2gc4impl12conservativeQw14ConservativeGC18fullCollectNoStackMFNbZv ()
#12 0x0000000000456ed6 in 
_D2gc4impl12conservativeQw14ConservativeGC14collectNoStackMFNbZv 
()
#13 0x0000000000446e21 in gc_term ()
#14 0x0000000000435bc3 in rt_term ()
#15 0x0000000000430882 in 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv ()
#16 0x0000000000430769 in 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ7tryExecMFMDFZvZv ()
#17 0x00000000004306d2 in _d_run_main2 ()
#18 0x000000000043048e in _d_run_main ()
#19 0x000000000042f6a2 in main ()
#20 0x00007ffff7c19e5b in __libc_start_main () from 
/lib64/libc.so.6
(gdb)

-----------------


So, first make a debug build of the program (dmd -g pain.d). 
Then, run the program in the debugger:

gdb ./pain

And then ask the debugger to break on this invalid operation:

break onInvalidMemoryOperationError

NOTE: the onInvalidMemoryOperationError is actually a function 
time inside druntime.

Then run the program with gdb's `r` command.

It breaks when that function is called, right before it actually 
would throw

Breakpoint 1, 0x00000000004614f8 in onInvalidMemoryOperationError 
()

So then I asked the debugger where this occurred:

(gdb) where

And visually scanned for a function I recognized (and my gdb also 
conveniently highlighted the filename in green)

#5  0x000000000042f65c in pain.Foo.~this() (this=0x7ffff7af1000) 
at pain.d:3

That looks like my code! pain.d line 3 caused the problem.

class Foo {
         ~this() {
                 auto a = new Object(); // this
         }
}

void main() {
         auto foo = new Foo();
}


It might not be this simple in a real bug situation - this 
program was specifically written to cause it - but the same 
approach should narrow it down pretty quickly for you.


More information about the Digitalmars-d-learn mailing list