2016-04-18 8 views
14

-rdynamic (या --export-dynamic लिंकर स्तर पर वास्तव में क्या करता है) -fvisibility* ध्वज या दृश्यता pragma एस और __attribute__ एस द्वारा परिभाषित अनुसार यह प्रतीक दृश्यता से कैसे संबंधित है?'गतिशील' क्या करता है और वास्तव में इसकी आवश्यकता होती है?

--export-dynamic के लिए, ld(1) का उल्लेख है:

... आप एक गतिशील वस्तु जो प्रतीकों कार्यक्रम द्वारा परिभाषित करने के लिए वापस उल्लेख करने की जरूरत है लोड करने के लिए उपयोग करें "dlopen", बल्कि कुछ अन्य गतिशील से हैं ऑब्जेक्ट, तो प्रोग्राम को लिंक करते समय आपको इस विकल्प का उपयोग करने के लिए शायद की आवश्यकता होगी। ...

मुझे यकीन नहीं है कि मैं इसे पूरी तरह से समझता हूं। क्या आप कृपया एक उदाहरण प्रदान कर सकते हैं जो -rdynamic के बिना काम नहीं करता है लेकिन इसके साथ करता है?

संपादित: मैं वास्तव में डमी पुस्तकालयों के एक जोड़े के संकलन की कोशिश की (एकल फाइल, बहु फ़ाइल, विभिन्न -O स्तर, कुछ अंतर-समारोह कॉल, कुछ छिपा प्रतीकों, कुछ दृश्य), के साथ और -rdynamic बिना, और अब तक मुझे बाइट-समान आउटपुट प्राप्त हो रहा है (जब सभी अन्य झंडे निरंतर रहते हैं), जो काफी परेशान है।

उत्तर

16

-rdynamic के उपयोग को चित्रित करने के लिए यहां एक साधारण उदाहरण परियोजना है।

bar.c

extern void foo(void); 

void bar(void) 
{ 
    foo(); 
} 

main.c

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

void foo(void) 
{ 
    puts("Hello world"); 
} 

int main(void) 
{ 
    void * dlh = dlopen("./libbar.so", RTLD_NOW); 
    if (!dlh) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    void (*bar)(void) = dlsym(dlh,"bar"); 
    if (!bar) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    bar(); 
    return 0; 
} 

Makefile

.PHONY: all clean test 

LDEXTRAFLAGS ?= 

all: prog 

bar.o: bar.c 
    gcc -c -Wall -fpic -o [email protected] $< 

libbar.so: bar.o 
    gcc -shared -o [email protected] $< 

main.o: main.c 
    gcc -c -Wall -o [email protected] $< 

prog: main.o | libbar.so 
    gcc $(LDEXTRAFLAGS) -o [email protected] $< -L. -lbar -ldl 

clean: 
    rm -f *.o *.so prog 

test: prog 
    ./$< 

यहाँ, bar.c हो एक साझा लाइब्रेरी libbar.so और main.c एक प्रोग्राम है जो dlopen s libbar और उस लाइब्रेरी से bar() पर कॉल करता है। bar()foo() पर कॉल करता है, जो bar.c में बाहरी है और main.c में परिभाषित है।

तो, -rdynamic बिना:

$ make test 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -o prog main.o -L. -lbar -ldl 
./prog 
./libbar.so: undefined symbol: foo 
Makefile:23: recipe for target 'test' failed 

और -rdynamic साथ:

$ make clean 
rm -f *.o *.so prog 
$ make test LDEXTRAFLAGS=-rdynamic 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -rdynamic -o prog main.o -L. -lbar -ldl 
./prog 
Hello world 
+0

आप उदाहरण यह पूरी तरह स्पष्ट करते हैं कि मैनपेज का क्या अर्थ है। आपका बहुत बहुत धन्यवाद! – PSkocik

2

मैं पश्व-अनुरेखन (का उपयोग कर बैकट्रैस प्रिंट करने की rdynamic का उपयोग करें)/backtrace_symbols() libc की।

गतिशील के बिना, आपको फ़ंक्शन नाम नहीं मिल सकते हैं।

बैकट्रैक() के बारे में और जानने के लिए यहां इसे पढ़ें। https://www.gnu.org/software/libc/manual/html_node/Backtraces.html

संबंधित मुद्दे