2016-05-08 9 views
3

Ich benutze dlsym, um Symbole in meinem Programm nachzuschlagen, aber es gibt immer NULL zurück, was ich nicht erwarte. Laut der Manpage kann dlsym NULL zurückgeben, wenn ein Fehler aufgetreten ist oder das Symbol tatsächlich NULL ist. In meinem Fall erhalte ich einen Fehler. Ich werde dir den MCVE zeigen, den ich heute Abend gemacht habe.dlsym gibt NULL zurück, obwohl das Symbol existiert

Hier ist der Inhalt von instr.c:

#include <stdio.h> 

void * testing(int i) { 
    printf("You called testing(%d)\n", i); 
    return 0; 
} 

Eine sehr einfache Sache, nur eine unauffällige Beispielfunktion enthält.

Hier ist der Inhalt von test.c:

#include <dlfcn.h> 
#include <stdlib.h> 
#include <stdio.h> 

typedef void * (*dltest)(int); 

int main(int argc, char ** argv) { 

    /* Declare and set a pointer to a function in the executable */ 
    void * handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); 
    dlerror(); 
    dltest fn = dlsym(handle, "testing"); 

    if(fn == NULL) { 
     printf("%s\n", dlerror()); 
     dlclose(handle); 
     return 1; 
    } 
    dlclose(handle); 
    return 0; 
} 

Als ich durch den Code mit dem Debugger Schritt, ich sehe die dlopen einen Griff zurückkehren. Nach der Manpage, If filename is NULL, then the returned handle is for the main program. Also wenn ich ein Symbol namens testing in das Hauptprogramm verknüpfen, sollte dlsym es finden, oder? Hier

ist die Art und Weise, die ich Kompilieren und Linken des Programms:

all: test 

instr.o: instr.c 
    gcc -ggdb -Wall -c instr.c 

test.o: test.c 
    gcc -ggdb -Wall -c test.c 

test: test.o instr.o 
    gcc -ldl -o test test.o instr.o 

clean: 
    rm -f *.o test 

Und wenn ich dieses Programm zu bauen, und dann tun objdump -t test | grep testing, ich sehe, dass das Symbol testing in der Tat gibt es:

08048632 g  F .text 00000020    testing 

Doch der Ausgang meines Programms ist der Fehler:

./test: undefined symbol: testing 

Ich bin mir nicht sicher, was ich falsch mache. Ich würde mich freuen, wenn jemand dieses Problem beleuchten könnte.

+2

http://coliru.stacked-crooked.com/a/3048847bea8edb97 Hinzufügen: '-Wl, - export-dynamic' lässt Ihr Programm arbeiten. Ohne es erhalten Sie den Fehler "undefined symbol: 'testing''. – Brandon

Antwort

4

Ich glaube nicht, dass Sie das tun können, funktioniert dlsym auf exportierte Symbole. Da Sie dlsym auf NULL (aktuelles Bild) tun, obwohl die Symbole im ausführbaren ELF-Bild vorhanden sind, werden sie nicht exportiert (da es keine gemeinsam genutzte Bibliothek ist).

Warum nicht direkt anrufen und sich vom Linker kümmern lassen? Es macht keinen Sinn, dlsym zu verwenden, um Symbole aus dem gleichen Bild wie Ihren dlsym Aufruf zu erhalten. Wenn sich Ihr testing Symbol in einer gemeinsam genutzten Bibliothek befindet, die Sie entweder verlinkt oder über dlopen geladen haben, können Sie es abrufen.

Ich glaube, es gibt auch eine Möglichkeit zum Exportieren von Symbolen beim Erstellen von ausführbaren Dateien (-Wl,--export-dynamic wie in einem Kommentar von Brandon erwähnt), aber ich bin mir nicht sicher, warum Sie das tun möchten.

+0

Es gibt wenig oder keinen Unterschied zwischen ELF-Programmen und ELF shared libraries. Tatsächlich enthalten einige gemeinsam genutzte Bibliotheken eine 'main()' -Funktion und können als Programme ausgeführt werden. Es gibt keinen besonderen Grund, warum ein ELF- "Programm" nicht als gemeinsam genutzte Bibliothek geladen werden konnte. Trotzdem bin ich sicher, dass Sie das Problem haben, dass das fragliche Symbol nicht exportiert wird. –