Ich jage eine Ausnahme, die von einem Teil des Codes, der vom Compiler nach jedem Aufruf an neue hinzugefügt wird geworfen wird. Es ist der Standard C++ neue, die etwas Speicher vom Heap erhalten und den Konstruktor der Klasse aufrufen sollte.Ausnahme von unerwartetem Assembler-Code nach einem Aufruf von new (Heap)
Wir betreiben VxWorks 5.5.1 mit GCC 2.95 (oder 2.96 nicht sicher) auf einem SH4-Prozessor. Kompiliert in SNiFF + 4.1 Patch 1.
Der C++ - Code sieht so aus.
CBlocksFile* pBlockFile = new CBlocksFile(szHeaderFile, szDataFile);
und der erzeugte Assembler-Code hat eine beenden/löschen/ Handhabung nach dem Aufruf neuen werfen. Dieses Muster scheint auf alle Anrufe an neue angewendet werden.
// 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
Wofür ist dieser Code nützlich? Es sieht nicht so aus wie die Bedingung "kein Speicher", da der Wurf nicht innerhalb der neuen Funktion liegt.
Warum wird der Wurf genannt? Und von wem? Es gibt das doppelte Muster, eine Codeadresse auf den Stack zu setzen, die später zur Ausführung verwendet werden kann.
Dank
Ist es Multi-Thread-Code? Überprüfe die Verwendung des Code-Speichers vor neuen Würfen. – DumbCoder
Es ist Single-Thread-Code. Für mich sieht es so aus, als würde new den Wurf nicht machen, weil ich in diesem Fall erwarten würde, __builtin_new auf dem Call-Stack zu sehen (und der Aufruf von ___sjthrow ist auf der gleichen Stack-Ebene wie der gezeigte Code). Oder es könnte ein erneuter Wurf sein, wenn eine Ausnahme behandelt wird, die vom Konstruktor ausgelöst wurde. Ich werde die Speichernutzung nächstes Jahr überprüfen. – Martin