
Ich habe eine gemeinsam genutzte Bibliothek kompiliert, die -g -O0
Folgendes enthält:
void MyClass::whatever()
{
...
doSomething(myImage, myPoints);
...
}
bool MyClass::doSomething(const Image& image, std::vector<cv::Vec2f>& points) const
{
const int32_t foo = 1;
const float bar = 0.1f;
...
}
Jetzt gehe ich whatever()
mit durch s
, aber es geht nicht in doSomething()
, sondern darüber hinweg. Es liegt nicht an der Verfügbarkeit der Quelle, denn (1) sie befindet sich in derselben Datei und (2) ich kann einen Haltepunkt in setzen doSomething()
und dort problemlos durch die Quellen gehen. Aber s
es scheint zu glauben, dass keine Quelle verfügbar ist.
Wenn ich set step-mode on
, erhalte ich eine Ausgabe wie
0xb5d51148 in myClass::doSomething (this=0xb25e4, image=...,
points=std::vector of length -91315, capacity 372871920 = {...})
from /path/to/myclass.so
wie Sie es bekommen, wenn keine Quelle verfügbar ist. Nach einer Weile wird n
die foo
Initialisierung mit der Quelle angezeigt. Es könnte also etwas inline
Magisches an meinem Parameter (ein opencv
Typ, Release-Build) sein, der am Anfang der Funktion steht. Ist es möglich, dass jemand gdb
dieses Zeug sieht, denkt „komisches Zeug, lass uns nach dieser Funktion weitermachen“ und nicht feststellt, dass für den Großteil der Funktion tatsächlich eine Quelle verfügbar ist?
(Falls es wichtig ist, es wurde mit LLVM/clang 3.5 auf einer ARM-Box mit Ubuntu kompiliert)
Antwort1
Dies ist wahrscheinlich ein Problem mit der GCC-Optimierung und der anschließendenZeilennummerntabelleerstellt vonZWERG das Karten
Speicheradressen, die den ausführbaren Code eines Programms enthalten, und die Quellzeilen, die diesen Adressen entsprechen
(Seite 8)
Die einfachste Lösung ist die Verwendungstepiwenn die Funktion erreicht ist
AusGDB-Benutzerhandbuch(Seite 65)
Schritt
Führen Sie Ihr Programm weiter aus, bis die Steuerung eine andere Quellzeile erreicht, stoppen Sie es dann und geben Sie die Kontrolle an gdb zurück.
....
Der Befehl „step“ stoppt nur bei der ersten Anweisung einer Quellzeile. Dies verhindert die mehrfachen Stopps, die sonst in Switch-Anweisungen, For-Schleifen usw. auftreten könnten. „step“ stoppt weiterhin, wenn innerhalb der Zeile eine Funktion aufgerufen wird, die Debuginformationen enthält. Mit anderen Worten: „step“ führt Schritte innerhalb aller Funktionen aus, die innerhalb der Zeile aufgerufen werden.
Außerdem ruft der Befehl „step“ eine Funktion nur dann auf, wenn Zeilennummerninformationen für die Funktion vorliegen. Andernfalls verhält er sich wie der nächste Befehl. Dadurch werden Probleme bei der Verwendung von cc -gl auf MIPS-Rechnern vermieden. Bisher rief „step“ Unterroutinen auf, wenn Debuginformationen zu der Routine vorlagen.