2009-09-21 12 views
35

कहें कि मेरे पास ब्ला और नामक दो प्रोग्राम हैं। मैं blah प्रोग्राम को डीबग करना चाहता हूं जो से प्रोग्राम I/O पुनर्निर्देशन के माध्यम से इनपुट प्राप्त करता है। मैं gdb का उपयोग कर निम्नलिखित मामले में blah प्रोग्राम कैसे डिबग करूं?gdb - पाइप के साथ डीबगिंग

bash> ret | blah 
+0

यह अलग है: http://stackoverflow.com/questions/4521015/how-to-pass-arguments-and-redirect-stdin-from-a-file-to-program-run-in-gdb –

उत्तर

41

सबसे पहले, आप प्रोग्राम चला सकते हैं और इसे पिड द्वारा डीबग कर सकते हैं। यह समाधान, ज़ाहिर है, सभी मामलों को कवर नहीं करता है।

एक और तरीका इंटर-प्रोसेस संचार के लिए लिनक्स क्षमताओं का उपयोग करना है। संक्षेप में, आप ret के आउटपुट को फीफो विशेष फ़ाइल ("नामित पाइप") पर रीडायरेक्ट करते हैं और फिर उस एफआईएफओ से डीबगर के माध्यम से पढ़ते हैं। यहां बताया गया है कि यह कैसे किया गया है। बैश से, चलाएँ:

mkfifo foo 

यह है कि एक नामित पाइप रूप में काम करेगा आपके निर्देशिका में एक विशेष फ़ाइल बनाता है। जब आप इस फ़ाइल में टेक्स्ट लिखते हैं (उसी वाक्यविन्यास echo "Hello" >foo का उपयोग करके), लेखन प्रोग्राम तब तक अवरुद्ध होगा जब तक कोई फ़ाइल से डेटा (cat <foo, उदाहरण के लिए) पढ़ता है। हमारे मामले में, इस फ़ाइल से एक जीडीबी नियंत्रित प्रक्रिया पढ़ी जाएगी।

के बाद आप एक फीफो, बैश से चलाने बनाया:

ret > foo & # ampersand because it may block as nobody is reading from foo 
gdb blah 

फिर, gdb प्रॉम्प्ट में, चलाने

run <foo 

और वांछित प्रभाव मिलता है। ध्यान दें कि आप फीफो (साथ ही सामान्य पाइप से) डेटा को दो बार पढ़ नहीं सकते हैं: जब आपने सभी डेटा पढ़ लिया है, तो blah प्रक्रिया मर जाती है और आपको foo को कमांड लिखना दोहराया जाना चाहिए (आप इसे कर सकते हैं अन्य खोल खिड़की से)।

जब आप पूरा कर लें, तो rm foo के साथ फीफो को हटा दें (या इसे उस निर्देशिका में रखें जहां इसे सिस्टम पुनरारंभ पर स्वचालित रूप से हटा दिया जाएगा, जैसे /tmp)।

+1

यदि आप डिस्क स्पेस को बर्दाश्त कर सकते हैं तो आप इसे फीफो 'foo' के बजाय नियमित फाइल' foo' में भी पाइप कर सकते हैं (आपको एक कमांड बचाता है :)। – Frank

+7

नियमित फाइलें और फीफो/पाइप के पढ़ने के लिए अलग-अलग अर्थशास्त्र होते हैं()। यदि आप नियमित फ़ाइल में ईओएफ तक पहुंचते हैं, तो निर्दिष्ट() निर्दिष्ट हो सकता है कि शायद निर्दिष्ट बाइट्स को निर्दिष्ट से पढ़ा जाए। यदि आप फीफो/पाइप से पढ़ते हैं, तब तक() ब्लॉक पढ़ें जब तक बाइट्स की निर्दिष्ट संख्या न आए, या पाइप को प्रक्रिया लिखना समाप्त हो गया हो। – SzG

9

जीडीबी का run आदेश पुनर्निर्देशन करने के लिए bash का उपयोग करता है। ret | blah के बराबर प्राप्त करने का एक आसान तरीका है बैश की process substitution सुविधा का उपयोग करना।

$ gdb blah 
... 
(gdb) run < <(ret) 

स्पष्टीकरण: बैश /dev/fd/123 की तरह कुछ है, जो ret की stdout की एक फ़ाइल की जानकारी देता है साथ <(ret) विकल्प। हम उस एफडी का उपयोग दूसरे नाम में वर्णित नामित फीफो के समान कर सकते हैं, सिवाय इसके कि हमें इसे मैन्युअल रूप से स्वयं नहीं बनाना है, न ही ret प्रक्रिया के जीवनकाल के बारे में चिंता करें।

+0

वास्तव में मेरी जरूरतों के अनुरूप है, धन्यवाद। – Limeth

+0

यह zsh के लिए काम नहीं करता है। क्या कोई विकल्प है? – redfast00

+0

प्रक्रिया प्रतिस्थापन zsh में समान कार्य करता है क्योंकि यह बैश में करता है। आपका आविष्कार क्या है और आपको किस त्रुटि संदेश का सामना करना पड़ता है? –