2012-08-29 13 views
6

मैं एक ऐसी परियोजना का निर्माण कर रहा हूं जो एकाधिक साझा पुस्तकालयों और निष्पादन योग्य फाइलें बनाता है। इन बाइनरी बनाने के लिए उपयोग की जाने वाली सभी स्रोत फ़ाइलें एक एकल/src निर्देशिका में हैं। तो यह पता लगाने के लिए स्पष्ट नहीं है कि कौन सी स्रोत फ़ाइलों का उपयोग प्रत्येक बाइनरी बनाने के लिए किया गया था (कई से कई संबंध हैं)।* .c और * .h फ़ाइलों को कैसे ढूंढें जिनका उपयोग बाइनरी बनाने के लिए किया गया था?

मेरा लक्ष्य एक ऐसी स्क्रिप्ट लिखना है जो प्रत्येक बाइनरी के लिए सी फाइलों के एक सेट को पार्स करे और सुनिश्चित करें कि केवल सही कार्य ही उनसे बुलाए जाते हैं।

एक विकल्प मेकफ़ाइल से इस जानकारी को निकालने का प्रयास करने लगता है। लेकिन यह जेनरेट की गई फाइलों और शीर्षकों (शामिल करने पर निर्भरता के कारण) के साथ अच्छी तरह से काम नहीं करता है।

कॉल ग्राफ़ ब्राउज़ करने के लिए एक और विकल्प हो सकता है, लेकिन यह जटिल हो जाएगा, क्योंकि फ़ंक्शन पॉइंटर्स का उपयोग करके बहुत सारे फ़ंक्शन बुलाए जाते हैं।

कोई अन्य विचार?

+1

जिज्ञासा से बाहर: आप यह क्यों कोशिश कर रहे हैं? – stefan

+0

वितरण पैकेज तंत्र सभी निर्भरताओं के बारे में जानता है ... –

+0

क्या आपके पास "सही कार्य कहलाता है" का सटीक परिभाषा है? यह स्पष्ट नहीं है और यह आसान नहीं है। –

उत्तर

6

आप पहली बार अपनी परियोजना को डीबग जानकारी (gcc -g) के साथ संकलित कर सकते हैं और 0 स्रोतों को प्राप्त करने के लिए objdump का उपयोग कर सकते हैं।

objdump -W <some_compiled_binary> 

बौने प्रारूप में वह जानकारी होनी चाहिए जिसमें आप खोज रहे हैं।

<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) 
    < c> DW_AT_producer : (indirect string, offset: 0x5f): GNU C 4.4.3 
    <10> DW_AT_language : 1 (ANSI C) 
    <11> DW_AT_name  : (indirect string, offset: 0x28): test_3.c  
    <15> DW_AT_comp_dir : (indirect string, offset: 0x36): /home/auselen/trials  
    <19> DW_AT_low_pc  : 0x82f0 
    <1d> DW_AT_high_pc  : 0x8408 
    <21> DW_AT_stmt_list : 0x0 

इस उदाहरण में, मैंने test_3 से ऑब्जेक्ट फ़ाइल संकलित की है, और यह .../परीक्षण निर्देशिका में स्थित था। फिर निश्चित रूप से संबंधित स्रोत फ़ाइल नाम एकत्र करने के लिए आपको इसके आसपास कुछ स्क्रिप्ट लिखनी होगी।

2

यहां एक विचार है, अपने विशिष्ट निर्माण के आधार पर परिष्कृत करने की आवश्यकता है। एक बिल्ड बनाएं, स्क्रिप्ट का उपयोग करके इसे लॉग करें (उदाहरण के लिए script log.txt make clean all)। आखिरी (या अंतिम में से एक) चरण वस्तु फ़ाइलों को जोड़ने का होना चाहिए। (युक्ति: cc -o <your_binary_name> देखें)। उस लाइन को सभी .o फ़ाइलों को लिंक करना चाहिए जो आपके पेड़ में संबंधित .c फाइलें होनी चाहिए। फिर उन सभी शामिल शीर्षलेख फ़ाइलों के लिए उन .c फ़ाइलों को grep।

यदि आपके पेड़ में .c फ़ाइलों में डुप्लिकेट नाम हैं, तो हमें लिंकर लाइन में पूरा पथ देखना होगा या Makefile से काम करना होगा।

नीचे महमूद सुझाव क्या काम करना चाहिए। यदि आपके पास प्रतीकों वाली छवि है, तो strings <debug_image> | grep <full_path_of_src_directory> आपको सी फाइलों की एक सूची देनी चाहिए।

+0

अच्छा विचार भी। लेकिन मैं जीसीसी के लिए मेकफ़ाइल से परिचित नहीं हूं लेकिन मैं वीएस के साथ करता हूं और वीएस उस विवरण को अधिक विवरण में नहीं दिखाएगा, यह आपके द्वारा लिंक की जा रही लाइब्रेरी फ़ाइलों को सरल सूची देगा। –

2

सबसे पहले आपको बस डिबग किए गए बाइनरी से डीबग प्रतीकों को अलग करने की आवश्यकता है। इस सवाल को कैसे करें: How to generate gcc debug symbol outside the build target?

फिर आप इस फ़ाइल को अपने आप पार्स करने का प्रयास कर सकते हैं। मुझे पता है कि विजुअल स्टूडियो के लिए ऐसा कैसे करना है, लेकिन जैसा कि आप जीसीसी का उपयोग कर रहे हैं, मैं आपकी मदद करने में सक्षम नहीं हूं।

+0

यह भी काम करना चाहिए! – jman

1

आप यूनिक्स nm उपकरण का उपयोग कर सकते हैं। यह ऑब्जेक्ट में परिभाषित सभी प्रतीकों को दिखाता है। अपने द्विआधारी पर

  • भागो ldd अपने द्विआधारी पर हड़पने के लिए अपने सभी गतिशील निर्भरता की सूची (.so फ़ाइलों को अपनी बाइनरी से जुड़ा हुआ है)
    1. भागो nm और हड़पने सभी अपरिभाषित प्रतीकों: तो आप की जरूरत है प्रत्येक .so फ़ाइल पर चलने nm कदम 2.

    है कि आप गतिशील प्रतीकों कि आपके द्विआधारी उपयोग की पूरी सूची दे देंगे में पाया youf।

    उदाहरण:

    nm -C --dynamic /bin/ls 
    ....skipping..... 
    00000000006186d0 A _edata 
    0000000000618c70 A _end 
           U _exit 
    0000000000410e34 T _fini 
    0000000000401d88 T _init 
           U _obstack_begin 
           U _obstack_newchunk 
           U _setjmp 
           U abort 
           U acl_extended_file 
           U bindtextdomain 
           U calloc 
           U clock_gettime 
           U closedir 
           U dcgettext 
           U dirfd 
    

    पूंजी के साथ उन सभी प्रतीकों "यू" ls कमांड द्वारा किया जाता है।

  • 1

    यदि आपका लक्ष्य सी स्रोत फ़ाइलों का विश्लेषण करना है, तो आप जीसीसी कंपाइलर को अनुकूलित करके ऐसा कर सकते हैं। आप उस उद्देश्य के लिए MELT का उपयोग कर सकते हैं (एमईएलटी जीसीसी का विस्तार करने के लिए एक उच्च स्तरीय डोमेन विशिष्ट भाषा है) - जीसीसी के अंदर एमईएलटी में कोडित अपने स्वयं के विश्लेषण पास को जोड़ना- लेकिन आपको सबसे पहले जीसीसी मध्य-अंत आंतरिक प्रतिनिधित्व (जीम्बल, ट्री) , ...)।

    जीसीसी को अनुकूलित करने में कई दिन काम लगते हैं (अधिकतर क्योंकि जीसीसी आंतरिक विवरण में काफी जटिल हैं)।

    मुझे एमईएलटी के बारे में और पूछने के लिए स्वतंत्र महसूस करें।

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

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