2009-10-19 9 views
7

कुछ परियोजनाओं में मैंने सी में किया है, मुझे निम्नलिखित मैक्रोज़ का उपयोग करना पसंद आया है जो पर्ल की चेतावनी और मरने वाले सबराउटिन के समान काम करते हैं:क्या पर्ल के कार्प मॉड्यूल के लिए कोई सी समतुल्य है?

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

#define warn(...) \ 
    fprintf(stderr, __VA_ARGS__); \ 
    fprintf(stderr, " at %s line %d\n", __FILE__, __LINE__) 

#define die(...) \ 
    warn(__VA_ARGS__); \ 
    exit(0xFF) 

क्या कुछ भी पर्ल की कार्प, क्रोक, क्लक, और स्वीकृति सबराउटिन की तरह मौजूद है Carp से? मैं उपयोगकर्ताओं के परिप्रेक्ष्य से त्रुटियों की रिपोर्ट करने के लिए कुछ करना चाहता हूं।

यदि नहीं, तो मुझे पता है कि glibce() और backtrace_symbols() glibc में फ़ंक्शंस हैं जो-गतिशील जीसीसी विकल्प के साथ मुझे फ़ंक्शन नामों और कोड पते के बैकट्रैक के साथ आपूर्ति कर सकते हैं। लेकिन मुझे कुछ बेहतर चाहिए; पर्ल के कॉलर सबराउटिन जैसे कॉल स्टैक में फ़ाइल, लाइन और फ़ंक्शन नामों तक पहुंच के साथ। इसके साथ में मैं अपने सी प्रोग्राम में उपयोग के लिए अपना खुद का libcarp लिखने में सक्षम होगा।

संपादित करें: 200 9 -10 x

मैं कुछ ऐसा बनाने की सोच रहा हूं जो बेसनेम (argv [0]) पर उपलब्ध होने पर gdb का उपयोग करता है, फिर विभिन्न प्रकार के संदेशों को उत्पन्न करने के लिए स्टैक ट्रेस को संसाधित करता है । यह निर्धारित करने में सक्षम होना चाहिए कि क्या मैं डीबग करने योग्य निष्पादन योग्य, या जीडीबी के बिना एक प्रणाली में नहीं हूं, इस मामले में, कार्प और क्लक चेतावनी बन जाएंगे और क्रोक और कबूल हो जाएगा।

Ive ने पहले कभी इस तरह gdb का उपयोग नहीं किया है (Ive केवल शुरुआत में ही मेरे प्रोग्राम के साथ इसे चलाता है, न कि यह पहले से चल रहा है)। लेकिन मुझे ग्लिब (g_on_error_stack_trace और stack_trace) में कुछ फ़ंक्शंस मिले जो कि मैं जो करना चाहता हूं उसके बहुत नज़दीक दिखता है: यह तर्कों के आधार पर एक जीडीबी प्रक्रिया को फोर्क करता है (argv [0]) और प्रक्रिया आईडी, फिर इसके stdin (जिसे एक पाइप पर रीडायरेक्ट किया गया है) "बैकट्रैक" कमांड के बाद "छोड़ें"। इसके बाद यह इसके परिणाम से पढ़ता है और जिस तरह से इसे पसंद करता है उसे पार करता है। यह लगभग वही है जो मुझे करने की ज़रूरत है।

+11

पर्ल, कार्प और क्रोक से अपरिचित लोगों के लिए उदाहरण जो चेतावनी देता है और मर जाता है मैक्रोज़ करता है, केवल वर्तमान उप के कॉलर से फ़ाइल और लाइन के साथ। क्लक और कबूल करें, केवल एक पूर्ण स्टैक ट्रेस के साथ ही करें। (कुछ विवरण सरलीकृत) – ysth

+4

डॉक्स पर: http://perldoc.perl.org/Carp.html – Ether

+4

सच बहु-कथन मैक्रोज़ के लिए, उन्हें अत्यधिक {...} जबकि (0) बनाने के लिए अत्यधिक अनुशंसा की जाती है अपेक्षित के रूप में एक कथन कार्य के रूप में उपयोग करें। – unwind

उत्तर

1

ठीक है, मैं कॉल स्टैक को दिखाने के लिए की कोशिश कभी नहीं, लेकिन मेरे कार्यक्रमों के लिए मैं निम्नलिखित करते थे।

पहले, मैं एक समारोह है कि वास्तविक प्रवेश कर परिभाषित करते हैं। यह सिर्फ एक उदाहरण है; कृपया ध्यान दें कि यह फ़ंक्शन अत्यधिक असुरक्षित है (बफर किसी को ओवररन करता है?)

void strLog(char *file, char *function, int line, char *fmt, ...) 
{ 
    char buf[1024]; 
    va_list args; 

    va_start(args, fmt); 
    vsprintf(buf, fmt, args); 
    va_end(args); 

    fprintf(stderr, "%s:%s:%d:%s\n", file, function, line, buf); 
} 

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

#define die(...) \ 
     strLog(__FILE__, __PRETTY_FUNCTION__, \ 
     __LINE__, __VA_ARGS__) 

तो फिर तुम सिर्फ printf() की तरह कह सकते हैं।

if (answer == 42) die("Oh, %d of course.", answer); 

और आप कुछ इस तरह मिलेगा:

main.c:10:somefunc: Oh, 42 of course. 

ठीक है, कोई पश्व-अनुरेखन लेकिन कुछ का कुछ।

+0

ऐसा लगता है कि जेक पहले से ही मिल चुका है। –

+2

बफर ओवररन को रोकने के लिए vsnprintf() का उपयोग करें। या उपयोगकर्ता द्वारा आपूर्ति स्वरूपण से निपटने के लिए fprintf() - फ़ाइल/फ़ंक्शन/लाइन जानकारी के लिए दो और vfprintf() के रूप में दो कॉल का उपयोग करें। प्रतीत होता है कि हर कोई कोड प्रोग्राम नाम मुद्रित करना भूल रहा है - argv [0]; हालांकि, कुछ सेटअप अनुशासन की आवश्यकता है। –

+1

यदि आप बफर ओवररन को रोकना चाहते हैं, तो इसे करने का सबसे आसान तरीका 'vsnprintf' के बजाय' vasprintf' को कॉल करना है। –

1

लेकिन मुझे पर्ल के कॉलर सबराउटिन जैसे कॉल स्टैक में फ़ाइल, लाइन और फ़ंक्शन नामों तक पहुंच के साथ कुछ बेहतर चाहिए।

समस्या यह है कि प्रोग्रामर से यह तय करने की आवश्यकता है कि सीमा आपके पुस्तकालय कोड और 'कॉलर' सबराउटिन के बीच सीमा कहां दिखाई दे। पर्ल ऐसा करने के लिए कुछ जादू (उर्फ हेरिस्टिक) का उपयोग करता है; हो सकता है कि आप बैकट्रैस फ़ंक्शंस के साथ ऐसा ही कर सकें। लेकिन सामान्य रूप से यह मामूली नहीं है।

+1

यहां निर्दिष्ट जादू कॉलर फ़ंक्शन है जो कि प्रदान की जाती है, कार्यों में से एक था। सी भाषा परिभाषा में कोई मानक कार्य नहीं है जो समकक्ष क्षमता प्रदान करता है। –

+0

मेरा मतलब था "यहां वर्णित जादू कॉलर फ़ंक्शन है जो कार्यों में निर्मित पर्ल में से एक के रूप में आपूर्ति की जाती है। सी भाषा परिभाषा में कोई मानक कार्य नहीं है जो समकक्ष क्षमता प्रदान करता है।" –

+1

@ डेविड: मुझे पता है कि आप क्या प्राप्त कर रहे हैं, और यह कठिन है कि सी में समतुल्य क्या होगा - कम से कम नहीं क्योंकि मानक सी वातावरण में समतुल्य नहीं है। और मेरी समझ यह है कि पर्ल 'कॉलर' अंतर्निर्मित पर्ल स्टैक या संबंधित डेटा से कॉलिंग फ़ंक्शन क्या है। –

0

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

मुझे पूरा यकीन है कि फ़ाइल और लाइन नंबर स्टैब्स सेगमेंट में भी हैं।

क्या यह ऐसी चीज की तरह लगता है जो आपकी मदद कर सकता है?

1

ऐसा प्रतीत होता है कुछ भी नहीं काफी सी कार्यक्रमों में उपयोग के लिए कार्प मॉड्यूल की तरह मौजूद है, तो मैं github पर यह करने के लिए एक छोटा सा पुस्तकालय लिखा था।

पुस्तकालय उपयोग के लिए परिभाषित निम्नलिखित निर्यात है:

warn, die 
carp, croak 
cluck, confess 

और मैं चेतावनी को errno तार जोड़ने के लिए पिछले अभियानों के ई-किस्मों जोड़ दिया है के बाद से मैं सोचा था कि यह उपयोगी होगा:

ewarn, edie 
ecarp, ecroak 
ecluck, econfess 

उदाहरण के लिए यदि आप एक पुस्तकालय लिख रहे हैं, तो और एक समस्या के बारे में कार्प करना चाहते हैं, बस का उपयोग

carp("%d is not a Fibonacci number!", 54); 

और यह आपकी लाइब्रेरी में कॉल करने वाले पहले फ़ंक्शन की फ़ाइल और लाइन नंबर प्रदर्शित करेगा।

पर्ल का कार्प मॉड्यूल संदिग्ध सबराउटिन खोजने के लिए फ़ाइल के बजाए एक अलग पैकेज का उपयोग करता है। यह संकुल के विश्वसनीय समूह के बाहर कौन सा सबराउटिन बाहर है यह निर्धारित करने के लिए यह @ISA सरणी या @CARP_NOT का पुनरावृत्ति उपयोग करता है। मैं इस तरह के कुछ जोड़ने का इरादा रखता हूं। यदि स्टैकट्रैक का शीर्ष भरोसेमंद दायरे में है, तो कार्प एक क्लक पर वापस आती है (जो समस्या का पूर्ण स्टैकट्रैक दिखाती है) जैसे कि यह लाइब्रेरी करेगा।

+0

एनबी: 2012-09-06 तक, गिथब लिंक 404 है। –

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