2008-09-24 14 views
29

क्या सी में संकलन समय पर फ़ंक्शन द्वारा आवश्यक स्टैक आकार को जानने और आउटपुट करने का कोई तरीका है? यहाँ मैं जानना चाहूंगा क्या है:संकलन समय पर स्टैक उपयोग की जांच

चलो कुछ समारोह लेते हैं:

void foo(int a) { 
    char c[5]; 
    char * s; 
    //do something 
    return; 
} 

जब इस समारोह संकलन, मुझे पता है कि यह कितना ढेर अंतरिक्ष उपभोग whent यह कहा जाता है जाएगा चाहते हैं। यह एक बड़ा बफर छुपा एक संरचना की ढेर घोषणा पर पता लगाने के लिए उपयोगी हो सकता है।

फ़ाइल foo.c:

मैं कुछ है कि कुछ इस तरह मुद्रित होता रहा हूँ समारोह foo ढेर उपयोग है n बाइट्स

वहाँ एक रास्ता उत्पन्न विधानसभा कि पता करने के लिए को देखने के लिए नहीं है ? या एक सीमा जिसे संकलक के लिए सेट किया जा सकता है?

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

चलो इसे एक और तरीका दें: क्या किसी ऑब्जेक्ट को स्थानीय ऑब्जेक्ट्स का आकार जानना संभव है? मुझे लगता है कि संकलक अनुकूलन मेरा मित्र नहीं होगा, क्योंकि कुछ चर गायब हो जाएंगे लेकिन बेहतर सीमा ठीक है।

+0

यदि आप सोच रहे थे, तो मैंने गुप्त '}' चरित्र टाइप किया है –

+0

प्रश्न मुझे अस्पष्ट लगता है। मुझे लगता है कि अगर आप यह जानना चाहते हैं कि आप इसे क्यों जानना चाहते हैं और डिस्सेप्लर या निष्पादन योग्य (जो कंपाइलर आउटपुट की जांच करने का सबसे आसान तरीका है) की जांच क्यों स्वीकार्य नहीं है, तो शायद किसी को कुछ आसान समाधान मिल सकता है? – Suma

उत्तर

10

लिनक्स कर्नेल कोड x86 पर 4K स्टैक पर चलता है। इसलिए वे परवाह करते हैं। वे इसे जांचने के लिए क्या उपयोग करते हैं, एक पर्ल स्क्रिप्ट है जिसे उन्होंने लिखा है, जिसे आप हाल ही में कर्नेल टैरबॉल में स्क्रिप्ट/चेकस्टैक.पी के रूप में पा सकते हैं (2.6.25 इसे मिला है)। यह objdump के उत्पादन पर चलता है, उपयोग दस्तावेज प्रारंभिक टिप्पणी में है।

मुझे लगता है कि मैंने पहले से ही इसे पहले से ही उपयोगकर्ता-स्थान बाइनरी के लिए उपयोग किया था, और यदि आप थोड़ा पर्ल प्रोग्रामिंग जानते हैं, तो इसे तोड़ना आसान है।

वैसे भी, यह मूल रूप से जीसीसी के आउटपुट पर देखने के लिए क्या करता है। और तथ्य यह है कि कर्नेल हैकर्स ने इस तरह के एक उपकरण को लिखा है कि जीसीसी के साथ ऐसा करने का कोई स्थिर तरीका नहीं है (या शायद यह हाल ही में जोड़ा गया था, लेकिन मुझे शक है)।

बीटीडब्ल्यू, मिंगव परियोजना और एक्टिवपेरल से ओबजडम्प के साथ, या सिग्विन के साथ, आप विंडोज़ पर और अन्य कंपाइलरों के साथ प्राप्त द्विआधारी पर भी ऐसा करने में सक्षम होना चाहिए।

+5

अद्यतन: माइकल ग्रीन ने नीचे उल्लेख किया है कि जीसीसी 4.6 में सी-gcc.gnu.org/gcc-4.6/changes.html के लिए उपलब्ध है। -फस्टैक-उपयोग नीचे शोडेनएक्स के उत्तर में नीचे वर्णित है: http://stackoverflow.com/a/126490/53974। – Blaisorblade

1

केवल संकलक वास्तव में जानता होगा, क्योंकि यह वह लड़का है जो आपकी सारी चीज़ें एक साथ रखता है। आपको जेनरेटेड असेंबली को देखना होगा और देखें कि प्रीम्बल में कितनी जगह आरक्षित है, लेकिन यह वास्तव में alloca जैसी चीज़ों के लिए जिम्मेदार नहीं है जो रनटाइम पर अपनी बात करते हैं।

+0

सैद्धांतिक रूप से स्थैतिक कोड विश्लेषक उपकरण ऐसे लिंट नौकरी कर सकते हैं, व्यावहारिक रूप से मुझे नहीं लगता कि वे ऐसा करते हैं। – Ilya

-1

सामान्य रूप से नहीं। सैद्धांतिक कंप्यूटर विज्ञान में हल करने की समस्या से पता चलता है कि आप यह भी अनुमान नहीं लगा सकते कि एक सामान्य प्रोग्राम किसी दिए गए इनपुट पर रोकता है या नहीं। सामान्य रूप से चलने वाले कार्यक्रम के लिए उपयोग किए गए स्टैक की गणना करना और भी जटिल होगा। तो: नहीं। शायद विशेष मामलों में।

मान लें कि आपके पास एक रिकर्सिव फ़ंक्शन है जिसका रिकर्सन स्तर इनपुट पर निर्भर करता है जो मनमाने ढंग से लम्बाई हो सकता है और आप पहले ही भाग्य से बाहर हैं।

+0

प्रक्रिया स्टैक के बारे में आपकी बात, इस बारे में नहीं कि फ़ंक्शन के लिए प्रत्येक कॉल – shodanex

+0

का उपयोग करेगा, रोक समस्या समस्या स्थिर विश्लेषण (यानी कंपाइलर्स में) को रोकती नहीं है, और प्रोग्राम टेक्स्ट को देखकर अनुमानित उत्तर देती है। वास्तव में, एक बड़ी चुनौती कंप्यूटिंग कर रही है जब दो अलग-अलग कार्यक्रम समकक्ष होते हैं, इसलिए दो समकक्ष कार्यक्रम स्थिर विश्लेषण के तहत अलग-अलग परिणाम दे सकते हैं। – Blaisorblade

3

मुझे नहीं पता कि एक स्थिर कोड विश्लेषण इस के लिए पर्याप्त पर्याप्त आंकड़ा क्यों नहीं दे सका।

किसी दिए गए फ़ंक्शन में सभी स्थानीय चर खोजने के लिए यह छोटा है, और प्रत्येक चर के लिए आकार सी मानक (प्रकारों में निर्मित) के माध्यम से या इसकी गणना करके (जटिल प्रकारों जैसे structs और यूनियनों के लिए) पाया जा सकता है। ।

निश्चित रूप से, उत्तर 100% सटीक होने की गारंटी नहीं दी जा सकती है, क्योंकि संकलक पैडिंग जैसे विभिन्न प्रकार के अनुकूलन कर सकता है, रजिस्टरों में चर डाल सकता है या अनावश्यक चर को पूरी तरह से हटा सकता है। लेकिन यह जो भी जवाब देता है वह कम से कम एक अच्छा अनुमान होना चाहिए।

मैंने एक त्वरित Google खोज की और StackAnalyzer पाया लेकिन मेरा अनुमान है कि अन्य स्थिर कोड विश्लेषण टूल में समान क्षमताएं हैं।

आप एक 100% सही आंकड़ा चाहते हैं, तो आप संकलक से उत्पादन को देखने या रनटाइम के दौरान यह जाँच करने के लिए होगा (राल्फ की तरह his reply में सुझाव दिया)

+1

स्टैकएनलियर अच्छा लगता है, लेकिन यह नौकरी का अनुरोध नहीं करता है, क्योंकि यह निष्पादन योग्य का विश्लेषण करता है, स्रोत कोड नहीं। इस तरह के उपकरण को लिखने के दौरान वास्तव में सिद्धांत में संभव होना चाहिए, मुझे ऐसा कोई बात नहीं है कि इस तरह के उपकरण मौजूद हैं - स्टैक उपयोग रनटाइम की जांच करना या assemly के आधार पर बहुत व्यावहारिक है। – Suma

+0

मैं सिर्फ एक फ़ंक्शन नाम कहता हूं, और आप जानते हैं कि फ़ंक्शन के उपयोग किए गए स्टैक स्पेस को प्राप्त करने के लिए स्थिर कोड विश्लेषण पर्याप्त क्यों नहीं है: alloca। जैसे ही एक फ़ंक्शन इसका उपयोग करता है (गैर कॉन्स वैल्यू के साथ) आप इसे नहीं बना सकते हैं। एक और बात पहले ही उल्लेख की गई है: रिकर्सन। – flolo

8

StackAnlyser निष्पादन योग्य कोड ही examinate करने लगता है प्लस कुछ डीबगिंग जानकारी। this reply द्वारा वर्णित किया गया है, जो मैं खोज रहा हूं, स्टैक विश्लेषक मेरे लिए अधिक दिखता है।

एडीए के लिए मौजूद कुछ भी ठीक होगा। कुटकी पुस्तिका से इस मैनुअल पृष्ठ को देखो:

22.2 स्टेटिक ढेर प्रयोग विश्लेषण

एक इकाई -fstack-उपयोग के साथ संकलित एक अतिरिक्त फ़ाइल का उपयोग किया जाता ढेर की अधिकतम राशि को निर्दिष्ट उत्पन्न होगा, एक प्रति समारोह पर आधार। फ़ाइल में एक .su एक्सटेंशन के साथ लक्ष्य ऑब्जेक्ट फ़ाइल के समान बेसनाम है। इस फ़ाइल की प्रत्येक पंक्ति तीन क्षेत्रों से बना है:

* The name of the function. 
* A number of bytes. 
* One or more qualifiers: static, dynamic, bounded. 

दूसरे क्षेत्र समारोह फ्रेम के ज्ञात भाग के आकार से मेल खाती।

क्वालीफायर स्थिर का अर्थ है कि फ़ंक्शन फ्रेम आकार पूरी तरह स्थिर है। इसका आमतौर पर मतलब है कि सभी स्थानीय चरों का स्थिर आकार होता है। इस मामले में, दूसरा क्षेत्र फ़ंक्शन स्टैक उपयोग का एक विश्वसनीय उपाय है।

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

+6

यह एक पुराना सवाल है, लेकिन एफसीसीआई जीसीसी 4.6 में -फस्टैक-उपयोग सी के लिए उपलब्ध है: http://gcc.gnu.org/gcc-4.6/changes.html –

+1

@ माइकल ग्रीन: यह एक जवाब हो सकता है! धन्यवाद ! – shodanex

1

मान लीजिए कि आप एक एम्बेडेड प्लेटफ़ॉर्म पर हैं, तो आप पाएंगे कि आपके टूलचेन पर यह जाना है। अच्छे वाणिज्यिक एम्बेडेड कंपाइलर्स (जैसे, उदाहरण के लिए आर्म/कील कंपाइलर) अक्सर स्टैक उपयोग की रिपोर्ट तैयार करते हैं।

बेशक, इंटरप्ट्स और रिकर्सन आमतौर पर उनके अलावा थोड़ा सा होता है, लेकिन अगर आपको किसी स्टैक पर एक मल्टी मेगाबाइट बफर के साथ कुछ भयानक स्क्रू-अप किया गया है तो यह आपको एक अजीब विचार देता है।

1

नहीं वास्तव में "समय संकलन", लेकिन मैं एक के बाद निर्माण कदम के रूप में यह करना होगा:

  • लिंकर मानचित्र फ़ाइल में प्रत्येक कार्य के लिए के लिए आप
  • मानचित्र फ़ाइल बना सकते हैं पढ़ा निष्पादन योग्य के संबंधित भाग, और समारोह प्रस्तावना का विश्लेषण करें।

यह स्टैकएनलिएज़र के समान है, लेकिन बहुत आसान है। मुझे लगता है कि निष्पादन योग्य या डिस्सेप्लर का विश्लेषण करना सबसे आसान तरीका है जिसे आप कंपाइलर आउटपुट में प्राप्त कर सकते हैं। जबकि संकलक आंतरिक रूप से उन चीज़ों को जानता है, मुझे डर है कि आप इसे प्राप्त नहीं कर पाएंगे (आप कार्यक्षमता को लागू करने के लिए कंपाइलर विक्रेता से पूछ सकते हैं, या यदि ओपन सोर्स कंपाइलर का उपयोग करते हैं, तो आप इसे स्वयं कर सकते हैं या किसी को ऐसा करने दे सकते हैं तुम्हारे लिए)।

इसे लागू करने के आप की जरूरत है:

  • मानचित्र फ़ाइल को पार्स करने
  • निष्पादन के प्रारूप
  • क्या एक समारोह प्रस्तावना की तरह लग सकता है और सक्षम हो समझ में सक्षम होने के लिए "डिकोड" यह

यह आपके लक्षित प्लेटफॉर्म पर कितना आसान या मुश्किल होगा। (एम्बेडेड? कौन सी सीपीयू आर्किटेक्चर? क्या कंपाइलर?)

यह सब निश्चित रूप से x86/Win32 में किया जा सकता है, लेकिन यदि आपने कभी ऐसा कुछ नहीं किया है और इसे स्क्रैच से सब कुछ बनाना है, तो आपके काम करने से कुछ दिन पहले लग सकते हैं और कुछ काम कर रहा है ।

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