Kann jemand dieses Verhalten von GDB erklären?
900 memset(&new_ckpt_info,'\0',sizeof(CKPT_INFO));
(gdb)
**903 prev_offset = cp_node->offset;**
(gdb)
**905 m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_** HDR),i_offset);
(gdb)
**903 prev_offset = cp_node->offset;**
(gdb)
**905 m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_ HDR),i_offset);**
(gdb)
**908 bitmap_offset = client_hdl/32;**
(gdb)
**910 bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908 bitmap_offset = client_hdl/32;**
(gdb)
**910 bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908 bitmap_offset = client_hdl/32;**
(gdb)
**910 bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
913 found = cpnd_find_exact_ckptinfo(cb , &ckpt_info , bitmap_offset , &offset , &prev_offset);
(gdb)
916 if(!found)
(gdb) p found
$1 = <value optimized out>
(gdb) set found=0
Left operand of assignment is not an lvalue.
Warum wird nach Ausführung von Zeile 903 dasselbe für 905 908 910 erneut ausgeführt?
Eine andere Sache ist found
eine bool
Variable vom Typ. Warum wird sie angezeigt value optimized out
? Ich kann den Wert auch nicht einstellen found
.
Dies scheint eine Compiler-Optimierung zu sein (in diesem Fall seine -O2
); Wie kann ich den Wert von noch einstellen found
?
Antworten:
Lernen Sie zum Debuggen von optimiertem Code die Assembler- / Maschinensprache.
Verwenden Sie den GDB-TUI-Modus. Meine Kopie von GDB aktiviert es, wenn ich das Minus und die Eingabetaste eingebe. Geben Sie dann Cx 2 ein (dh halten Sie die Strg-Taste gedrückt und drücken Sie X, lassen Sie beide los und drücken Sie dann 2). Dadurch wird die Anzeige für geteilte Quellen und Demontage angezeigt. Verwenden Sie dann
stepi
undnexti
, um jeweils eine Maschinenanweisung zu verschieben. Verwenden Sie Cx o, um zwischen den TUI-Fenstern zu wechseln.Laden Sie ein PDF über die Maschinensprache Ihrer CPU und die Funktionsaufrufkonventionen herunter. Sie werden schnell erkennen, was mit Funktionsargumenten und Rückgabewerten gemacht wird.
Sie können den Wert eines Registers mit einem GDB-Befehl wie anzeigen
p $eax
quelle
Ohne Optimierungen neu kompilieren (-O0 auf gcc).
quelle
Declare gefunden als „flüchtig“. Dies sollte den Compiler anweisen, es NICHT zu optimieren.
quelle
Der Compiler wird mit aktivierten Optimierungen sehr clevere Dinge tun. Der Debugger zeigt den Code an, der aufgrund der optimierten Art und Weise, wie Variablen in Registern gespeichert werden, viel vorwärts und rückwärts springt. Dies ist wahrscheinlich der Grund, warum Sie Ihre Variable nicht festlegen können (oder in einigen Fällen ihren Wert sehen können), da sie aus Geschwindigkeitsgründen geschickt zwischen den Registern verteilt wurde, anstatt über einen direkten Speicherort zu verfügen, auf den der Debugger zugreifen kann.
Ohne Optimierungen kompilieren?
quelle
In der Regel werden boolesche Werte, die unmittelbar nach ihrer Berechnung in Zweigen verwendet werden, nie tatsächlich in Variablen gespeichert. Stattdessen verzweigt der Compiler direkt von den Bedingungscodes , die aus dem vorherigen Vergleich festgelegt wurden. Beispielsweise,
Kompiliert normalerweise zu etwas wie:
Beachten Sie, dass der "Bool" niemals irgendwo gespeichert wird.
quelle
Sie können den Wert von found so gut wie nicht festlegen. Das Debuggen optimierter Programme ist selten die Mühe wert. Der Compiler kann den Code so neu anordnen, dass er in keiner Weise dem Quellcode entspricht (außer dass das gleiche Ergebnis erzielt wird), wodurch die Debugger ohne Ende verwirrt werden.
quelle
Beim Debuggen optimierter Programme (was erforderlich sein kann, wenn der Fehler in Debug-Builds nicht auftritt) müssen Sie häufig den generierten Assembly-Compiler verstehen.
In Ihrem speziellen Fall wird der Rückgabewert von
cpnd_find_exact_ckptinfo
in dem Register gespeichert, das auf Ihrer Plattform für Rückgabewerte verwendet wird. Aufix86
, das wäre%eax
. Einx86_64
:%rax
usw. Möglicherweise müssen Sie nach der Konvention zum Aufrufen der Prozedur [Ihres Prozessors] googeln, wenn dies nicht der Fall ist.Sie können dieses Register in überprüfen
GDB
und festlegen. ZB amix86
:quelle
Ich benutze QtCreator mit GDB.
Hinzufügen
Funktioniert gut für mich
quelle