I am chasing an exception which is thrown from a part of code which is added by the compiler after each call to new. It's the standard C++ new, which should get some memory from the heap and call the constructor of the class.
We are running VxWorks 5.5.1 with GCC 2.95 (or 2.96 not sure about that) on a SH4 processor. Compiled within SNiFF+ 4.1 Patch 1.
The C++ codes looks like this.
CBlocksFile* pBlockFile = new CBlocksFile(szHeaderFile, szDataFile);
And the generated assembler code has a terminate/delete/throw handling after the call to new. This pattern seems to be applied on all calls to new.
// call to "new"
c4d6000 d14d mov.l @(0x134,pc),r1 (= 0x0c06c1e0 = ___builtin_new)
c4d6002 410b jsr @r1
c4d6004 e414 (mov #20,r4)
...
// compiler generates throw path address
c4d6022 d246 mov.l @(0x118,pc),r2 (= 0x0c4d6034)
...
// and pushes it to the stack
c4d602c 1121 mov.l r2,@(4,r1)
...
c4d6030 a002 bra +4 (==> 0x0c4d6038 : GOOD_PATH)
...
// throw path (there is no visible jump to this address)
c4d6034 a088 bra +272 (==> 0x0c4d6148 : THROW_PATH)
...
GOOD_PATH:
...
// call to constructor
c4d6058 d139 mov.l @(0xe4,pc),r1 (= 0x0c4d1730 T ___Q211CBlocksFilePCcT1bUcl)
...
c4d6060 410b jsr @r1
...
// normal path
return
THROW_PATH:
...
// same pattern again, compiler generates terminate path address
c4d6164 d22f mov.l @(0xbc,pc),r2 (= 0x0c4d6172)
...
// and pushes it to the stack
c4d616a 1121 mov.l r2,@(4,r1)
...
c4d616e a002 bra +4 (==> 0x0c4d6176 : NO_TERMINATE)
...
c4d6172 a039 bra +114 (==> 0x0c4d61e8 : TERMINATE_A)
...
NO_TERMINATE:
...
// delete handling
if ( ?? )
c4d617c 2118 tst r1,r1
c4d617e 8d04 bt/s +8 (==> 0x0c4d618a)
...
{
delete ??
...
c4d6184 d128 mov.l @(0xa0,pc),r1 (= 0x0c06be20 = ___builtin_delete)
c4d6186 410b jsr @r1
...
}
c4d618a 9044 mov.w @(0x88,pc),r0 (= 0x0000028c)
c4d618c 02ee mov.l @(r0,r14),r2
c4d618e 5121 mov.l @(4,r2),r1
c4d6190 6112 mov.l @r1,r1
c4d6192 1211 mov.l r1,@(4,r2)
c4d6194 d125 mov.l @(0x94,pc),r1 (= 0x0c06a880 = ___sjthrow)
c4d6196 410b jsr @r1
For what is this code snipped useful? It does not look like the no memory condition, because the throw is not within the new function.
Why is the throw called? And from whom? There is twice this pattern of putting a code address onto the stack, which might be used for execution later on.
Thanks
A guess would be that this pattern is applied because it is a requirement of c++ that if the constructor throws, the memory for the object should be freed. So if an exception is thrown from within the constructor, the newly allocated object gets deleted.
You could always try to explicitly throw something from the constructor of your object to see which path execution takes to verify whether or not this answer is useful.
I want to give a quick answer to my own question after the issue is solved.
I've added a new failure handler to see if it would be called. And it was called right before the mentioned exception would have been thrown. So it turned into an 'out of memory condition' and within a few hours I've found the memory leak.
It seems that in VxWorks you don't see the 'new' function call in the stack trace in case of an exception thrown after an out of memory condition.
Thanks to DumpCoder and villintehaspam, they made me thinking into the right direction.
User contributions licensed under CC BY-SA 3.0