2009-06-24 16 views
7

पर एक (धीमी) लिंकर डीबग करें मेरी कंपनी में हमारे लिंकर (एलडी 2.17) के साथ हमें वास्तव में परेशानी की समस्या है। यह अपेक्षाकृत तेज़ सिस्टम (कोर डुओ, 2 जीबी राम) पर बहुत धीमा है और मैं वास्तव में इसे ठीक करने के लिए वास्तव में नहीं हूं। अपेक्षाकृत बड़ी परियोजना को संकलित करने में लगभग पांच से दस मिनट लगते हैं (जो मेरे जेनेटू सिस्टम पर लिंक करने में लगभग 5 सेकंड लगते हैं)।कैसे एक डेबियन सिस्टम

व्यक्तिगत रूप से मुझे लगता है कि यह मेरे लिए कम से कम एक उत्पादकता हत्यारा है। हमने एलडी (2.1 9) के एक और हालिया संस्करण का उपयोग करने की कोशिश की लेकिन बिना किसी सफलता के। मैंने #freenode पर #debian में पूछा, लेकिन यह समस्या बहुत ही अद्वितीय प्रतीत होती है। मुझे नेट पर समान समस्याओं के बारे में कोई जानकारी नहीं मिली। यह तब होता है जब हम डीबग प्रतीकों के साथ बनाते हैं। मैंने जीसीसी डीबग-सूचना झंडे को -g, -g3, और -ggdb में बदल दिया, लेकिन इससे कोई मदद नहीं मिली।

तो मेरा सवाल यह है कि आप एक लिंकर को कैसे प्रोफाइल और डिबग करते हैं? मैंने कभी ऐसा कुछ नहीं किया है, और मैं इसके बारे में कोई दस्तावेज नहीं ढूंढ पा रहा हूं। असल में कोई भी उचित gprof gmon.out बहुत उपयोगी होगा, क्योंकि मैं binutils डेवलपर्स को एक ठोस समस्या के बारे में पूछ सकता हूं। मैं इसके बारे में पूरी तरह से अनजान हूँ।

संपादित करें: हमने अधिकांश सिस्टम पर डेबियन लेनी पर स्विच करने में हमारी समस्या को ठीक किया है। उत्तर के लिए धन्यवाद!

उत्तर

5

आप मंदी gcc चल रहा है (जैसा कि सीधे ld के रूप में लिंकर चल के खिलाफ) को देख रहे हैं, तो इस तरह के आंतरिक collect2 और के रूप में सभी मध्यस्थ आदेश, बाहर प्रिंट होगा

 
$ gcc -save-temps -v [... rest of your command line ...] 

साथ संकलन की कोशिश अंतिम ld, साथ ही यह सुनिश्चित करता है कि कमांड पूरा होने के बाद भी उन आदेशों को पारित ऑब्जेक्ट डिस्क पर रहेगा।

फिर आप सबसे खराब चरण खोजने के लिए व्यक्तिगत रूप से आदेश चलाने में सक्षम होना चाहिए, और फिर इसे विभिन्न विकल्पों या प्रोफाइलिंग के साथ चलाएं।

उदाहरण के लिए,

 
$ echo 'int main() {}' > test.c 
$ gcc -save-temps -v test.c 
Using built-in specs. 
Target: x86_64-pc-linux-gnu 
Configured with: /var/tmp/paludis/sys-devel-gcc-4.3.3-r2/work/gcc-4.3.3/configure --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.3.3 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.3.3 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.3.3/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.3.3/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include/g++-v4 --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec --disable-fixed-point --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --enable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --enable-cld --disable-libgcj --enable-objc-gc --enable-languages=c,c++,objc,obj-c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.3.3-r2 p1.1, pie-10.1.5' 
Thread model: posix 
gcc version 4.3.3 (Gentoo 4.3.3-r2 p1.1, pie-10.1.5) 
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic' 
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/cc1 -E -quiet -v test.c -D_FORTIFY_SOURCE=2 -mtune=generic -fpch-preprocess -o test.i 
ignoring nonexistent directory "/usr/local/include" 
ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/include" 
#include "..." search starts here: 
#include search starts here: 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include-fixed 
/usr/include 
End of search list. 
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic' 
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/cc1 -fpreprocessed test.i -quiet -dumpbase test.c -mtune=generic -auxbase test -version -o test.s 
GNU C (Gentoo 4.3.3-r2 p1.1, pie-10.1.5) version 4.3.3 (x86_64-pc-linux-gnu) 
     compiled by GNU C version 4.3.3, GMP version 4.2.4, MPFR version 2.4.1-p5. 
warning: GMP header version 4.2.4 differs from library version 4.3.1. 
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 
Compiler executable checksum: 20f3dbffbfd03e5311a257ae1239cd71 
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic' 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/bin/as -V -Qy -o test.o test.s 
GNU assembler version 2.19.1 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.19.1 
COMPILER_PATH=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/libexec/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/libexec/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/bin/ 
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../:/lib/:/usr/lib/ 
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic' 
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../.. test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crtn.o 
$ ls 
a.out test.c test.i test.o test.s 
$ /usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../.. test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crtn.o 
$ .../collect2 -v ... 
collect2 version 4.3.3 (x86-64 Linux/ELF) 
/usr/bin/ld -v --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../.. test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crtn.o 
GNU ld (GNU Binutils) 2.19.1 
$ 

आप ld की एक डिबग संस्करण के निर्माण में मदद की जरूरत है, यहाँ एक त्वरित नुस्खा तुम जा पाने के लिए है।

 
$ sudo apt-get install build-essential dpkg-dev 
$ sudo apt-get build-dep binutils 
$ apt-get source binutils 
$ cd binutils-* 
$ DEB_BUILD_OPTIONS='debug noopt nostrip' dpkg-buildpackage -uc -us 
$ cd .. 
$ sudo dpkg -i *.deb 

इसके बजाय कि त्वरित हैक की है, हालांकि, मैं schroot या sbuild का उपयोग कर अपनी खुद की प्रणाली प्रदूषण से बचने के लिए सलाह देते हैं।

+0

"नहीं तो स्पष्ट डेबियन समर्थन" और जीसीसी झंडा :) – tr9sh

+0

@ephemient मैं ld.so के लिए स्रोत पर कदम कोशिश कर रहा हूँ और स्रोत कोड लाइन GDB में क्रियान्वित किया जा रहा है देखने के लिए चाहते हैं के लिए +1। मैंने binutils-source और libcdbg स्थापित किया है लेकिन जीडीबी दिखाता है कि नियंत्रण ld.so कोड में प्रवेश करते समय सॉरसे उपलब्ध नहीं है। क्या आप कृपया सुझाव दे सकते हैं कि मैं क्या खो रहा हूं। धन्यवाद http://stackoverflow.com/questions/20114565/gdb-step-into- गतिशील- linkerld-so-code – abhi

6

आप ld के बजाय सोने (binutils-gold) का प्रयास कर सकते हैं। यह तेजी से होना चाहिए।

यहाँ एक लिंकर जीएनयू लिंकर [3] की तुलना में तेजी है, विशेष रूप से C++ कोडित बड़े अनुप्रयोगों के लिए बनाने से Wikipedia Gold(linker)

एक बोली सोने लिखने के लिए प्रेरणा के लिए किया गया है।

सोने के लेखक (इयान लांस टेलर) an (longish) article about linkers प्रकाशित किया है जहां वह सोने लिखित रूप में अपने रूपांकनों बताते हैं और क्यों सबसे linkers धीमी गति से कर रहे हैं। यदि आप लिंकर्स के आंतरिक कार्यों में रूचि रखते हैं तो यह लेख पढ़ने योग्य है।

+1

धन्यवाद, मुझे सोने के बारे में पता है, लेकिन हम इसे आगे बढ़ने के लिए तैयार नहीं हैं – tr9sh

3

प्रोफाइलिंग प्रश्न का उत्तर देने के लिए; आपको OProfile पर देखना चाहिए - यह एक सिस्टम-स्तरीय प्रोफाइलर है जो कई चल रही प्रक्रियाओं को प्रोफाइल कर सकता है। यह आपको यह पहचानने की अनुमति दे सकता है कि लिंक की कौन सी उप-प्रक्रिया सबसे अधिक समय ले रही है, और इसके अलावा यह दिखाएगा कि कौन सा कार्य सबसे अधिक समय व्यतीत किया जा रहा है।

1

मैं जाँच करने के लिए दो तरीके सुझाव देना चाहते हैं:

  1. उपयोग strace क्या फ़ाइलें लिंकर लोड कर रहा है/लिंक को पार्स करने की जांच करने के लिए; इसके साथ आप जान सकते हैं कि लिंकर द्वारा कोई अनावश्यक पथ खोजा गया है।
  2. एलडीडी के साथ एलडी का उपयोग करें यह जानने के लिए कि एलडी क्या कर रहा है। पांच मिनट की तुलना में पांच मिनट लिंकर की समस्या नहीं होनी चाहिए, यह आपकी मेजबान मशीन या कुछ विकल्प की कुछ समस्या होनी चाहिए।
संबंधित मुद्दे