Forum: PC-Programmierung C++ stacktraces


von Gustav G. (gustavgggg)


Lesenswert?

Ich möchte in einem Handler gerne sinnvolle stacktraces generieren. Im 
Moment passiert das mit boost stacktrace, was auch funktioniert. 
Allerdings möchte ich meine executables in Zukunft nicht mehr mit allen 
Debuginformationen ausliefern. Erstens erschwert es reverse engineering 
und zweitens macht es das kleiner. Dabei gehen natürlich lesbare 
stacktraces verloren.

Es sind dann nur noch frame pointer vorhanden, die ich wieder in 
Funktionen übersetzen muss. Hat jemand dazu eine Idee. Ich habe mir mal 
breakpad oder crashpad angesehen aber das ist zu viel Aufwand. Ideal 
wäre ein kleines tool, dass mit einen stacktrace ausgeben kann.

von Udo K. (udok)


Lesenswert?

Ich verwende Microsoft Visual Studio, da ist die Debug Info getrennt von 
der exe in einem PDB File (wird per default erzeugt) - ohne das PDB 
kannst du nur in ASM debuggen.  Das Linker Flag /pdbstripped entfernt 
noch zusätzliche private Infos aus der exe. Die MiniDumpWriteDump 
Funktion schreibt dir ein Dump File mit spezifischen Einstellungen, oder 
du nimmst die Default Einstellungen von Windows Error Reporting, die bei 
einem Program Crash ein Dump File erzeugt.  Siehe hier:
https://learn.microsoft.com/de-de/windows/win32/wer/collecting-user-mode-dumps

: Bearbeitet durch User
von Gustav G. (gustavgggg)


Lesenswert?

Udo K. schrieb:
> Ich verwende Microsoft Visual Studio, da ist die Debug Info
> getrennt von
> der exe in einem PDB File (wird per default erzeugt) - ohne das PDB
> kannst du nur in ASM debuggen.  Das Linker Flag /pdbstripped entfernt
> noch zusätzliche private Infos aus der exe. Die MiniDumpWriteDump
> Funktion schreibt dir ein Dump File mit spezifischen Einstellungen, oder
> du nimmst die Default Einstellungen von Windows Error Reporting, die bei
> einem Program Crash ein Dump File erzeugt.  Siehe hier:
> https://learn.microsoft.com/de-de/windows/win32/wer/collecting-user-mode-dumps

Was wäre denn die Linux Variante das zu machen?

von Oliver (imonbln)


Lesenswert?

Gustav G. schrieb:
> Was wäre denn die Linux Variante das zu machen?

Das Programm mit debug symbols zu bauen und dann mit objcopy die 
Debugsymbole in eine eigene Datei abspalten.

https://sourceware.org/gdb/current/onlinedocs/gdb.html/Separate-Debug-Files.html 
verrät dir alle Details.

von Gustav G. (gustavgggg)


Lesenswert?

Oliver schrieb:
> Gustav G. schrieb:
>> Was wäre denn die Linux Variante das zu machen?
>
> Das Programm mit debug symbols zu bauen und dann mit objcopy die
> Debugsymbole in eine eigene Datei abspalten.
>
> https://sourceware.org/gdb/current/onlinedocs/gdb.html/Separate-Debug-Files.html
> verrät dir alle Details.

Danke. Das hilft schonmal. Wenn ich debuggen will und ein core file habe 
ist das so möglich. Ich habe allerdings nur den Stacktrace mit adressen 
und kann später nichts mehr debuggen. Alle corefiles zu behalten würde 
sehr viel speicher nehmen.

von Oliver (imonbln)


Lesenswert?

Gustav G. schrieb:
> Ich habe allerdings nur den Stacktrace mit adressen
> und kann später nichts mehr debuggen.

Aber du kannst dein Programm in den gdb mit Debug Informationen laden 
und dann mit
1
 info line *<addr>

die Adresse in die Zeile konvertieren. Außerdem gibt es noch das 
Programm addr2line https://linux.die.net/man/1/addr2line welches 
mithilfe der Separaten Debugg Informationen die Adresse in Zeilennummern 
übersetzt.

von Max H. (nilsp)


Lesenswert?

Was die anderen Sagen.

Zusätzlich kannst Du unter Linux mit addr2line das ganze auch 
automatisieren.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Gustav G. schrieb:
> Was wäre denn die Linux Variante das zu machen?

#include <backtrace.h> und backtrace()?

https://linux.die.net/man/3/backtrace

Das setzt allerdings voraus, dass du die Möglichkeit hast das 
aufzurufen, etwa in einer eigenen fatal() Funktion.  Evtl. entsprechende 
Signals implementieren.

Dann gibt's auch backtrace_symbols(), allerdings braucht das malloc(), 
was man in so einem Handler nicht unbedingt haben will.

backtrace_symbols_fd() braucht kein malloc(), schreibt aber auf einen 
File Descriptor; ist also auch nicht 100% unproblematisch mit 
schlechterer Usability.  Kann aber auch nützlich nein, wenn der Kunde 
einem "nur" crash.txt zusenden muss.

Und addr2line wurde ja schon genannt.

Um kleineres Binary ohne Debug- oder Symbolinfo zu erhalten geht auch 
strip oder strip -g etc.

https://linux.die.net/man/1/strip

Ansonten ist das Binary gleich, und die ungestrippte Version kannst du 
behalten.

von Foobar (asdfasd)


Lesenswert?

> Was wäre denn die Linux Variante das zu machen?

core files erlauben (ulimit -S -c unlimited) und das dann nach einem 
crash ("core dumped") mit gdb anschauen.

von Rolf M. (rmagnus)


Lesenswert?

Johann L. schrieb:
> backtrace_symbols_fd() braucht kein malloc(), schreibt aber auf einen
> File Descriptor; ist also auch nicht 100% unproblematisch mit
> schlechterer Usability.  Kann aber auch nützlich nein, wenn der Kunde
> einem "nur" crash.txt zusenden muss.

Der fd kann ja auch STDERR_FILENO sein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.