gdb und dlopen()

21/04/2011 - 14:47 von Ole Streicher | Report spam
Hallo,

ich habe ein Programm, welches eine spezifizierte Shared Library mit
dlopen() öffnet und Funktionen daraus ausführt. Im Fehlerfalle (SIGSEV)
möchte ich gerne einen Stacktrace davon haben.

Also ein Signalhandler installiert, der sich im Fehlerfall mit gdb
verbindet und einen Stacktrace abspeichert. Etwa so:

static void segv_handler(int sig) {
char cmd[100];
snprintf(cmd, sizeof(cmd),
"echo Received signal: %i > backtrace", sig);
system(cmd);
gdb_commands = "cat >> gdb_commands << EOF"
"set height 0"
"set width 0"
"bt full
"info sources"
"EOF";
system(gdb_commands);
snprintf(cmd, sizeof(cmd),
"gdb -batch -x gdb_commands --pid %i >> backtrace 2> /dev/null",
(int)getpid());
system(cmd);
unlink("gdb_commands");
signal(sig, SIG_DFL);
}

int main(void) {
void *handle = dlopen("mylib.so", RTLD_LAZY);
int (*exec)() = dlsym(handle, "my_exec"); // Fehlerbehandlung hier weggelassen

signal(SIGSEGV, (sighandler_t) segv_handler);
return exec();
}

Das Problem ist nun, dass auf Scientific Linux/RHEL 6.0 keine Symbole
aus der Bibliothek mylib.so angezeigt werden, selbst wenn diese mit -g
übersetzt wurde. Gerade die sind aber jene, die mich eigentlich
interessieren.

Auf anderen Maschinen (Ubuntu 10.10) funktioniert das jedoch.

Wie kann man das (portabel für Linux und MacOS X) lösen? Ich hatte schon
versucht, den Debugger mit "--load mylib.so" u.à. aufzurufen, aber
das fuinktioniert nicht. Gdb kennt auch die Option "add-symbol-file",
die benötigt jedoch neben dem Dateinamen auch die Speicheradresse, und
die kenne ich ja auch nicht, oder?

Viele Grüße

Ole
 

Lesen sie die antworten

#1 Jan Seiffert
21/04/2011 - 17:25 | Warnen spam
Ole Streicher schrieb:
Hallo,



[snip]
Das Problem ist nun, dass auf Scientific Linux/RHEL 6.0 keine Symbole
aus der Bibliothek mylib.so angezeigt werden, selbst wenn diese mit -g
übersetzt wurde. Gerade die sind aber jene, die mich eigentlich
interessieren.

Auf anderen Maschinen (Ubuntu 10.10) funktioniert das jedoch.

Wie kann man das (portabel für Linux und MacOS X) lösen?



AFAIK Garnicht.
Hoffen und beten.
(Dein handler (ich hab selber sowas...) ist schon unportabel und eigentlich
"verboten", du solltest *printf nicht aus einem signal handler aufrufen, die
koennten einen lock gesetzt haben)

Es kommt drauf an das die Umgebung zum debuggen richtig eingerichtet ist, und
das ist nicht immer gegeben.

Man kann z.B. Split-debug haben (die Debug-sections werden in eigenen Dateien
gehalten), so dass das normale packet installiert ist, das debug packet und
damit die Debug info aber fehlen.
Oder der Debugger findet sie einfach nicht im split debug Szenario.
Oder oder oder

Ich glaube da ist sowieso ein Problem mit dlopen'ed libs, das die "zu frueh"
wieder entladen werden, so das die symbole fehlen (Valgrind hat auch solche
probleme).

Schau mal ob du symbole bekommst wenn du die Lib fest dazu linkst, spiel mal mit
LD_LIBRARY_PATH/ld.so.conf rum, was du bekommst wenn du ueber
-Wl,rpath,/foo/blah/troet (oder wie das hiess) den pfad zu deiner Lib dem
Programm mitgibst.

Oder versuch mal folgendes (ungetested, nur ums zu illustrieren, ohne
fehlerbehandlung):

char cmd[1024];
char *wptr;
int ret_val;

wptr = strpcpy(cmd, "gdb -nw -q -r ");
ret_val = readlink("/proc/self/exe", wptr, cmd+(sizeof(cmd)-1)-wptr);
wptr += ret_val;
*wptr++ = ' ';
wptr = itoa(wptr, (int)getpid());
*wptr++ = ' ';
wptr = strpcpy(wptr, "<<EOFset height 0set width 0"
"bt fullinfo sourcesEOF ");
wptr = strpcpy(wptr, ">> backtrace 2> /dev/null");
*wptr = '\0';

system(cmd);


[snip]

Viele Grüße

Ole



Gruss
Jan

Ähnliche fragen