2016-01-18 3 views
9

समस्याgdb जब मैं डोकर कंटेनर के अंदर से इसे चलाने के लिए किसी भी breakpoints हिट नहीं करता

मैं सेट और अगर मैं संकलन और मेजबान से चलाने के एक ब्रेकपाइंट तक पहुँचते हैं, लेकिन अगर मैं भीतर से यह करने के लिए कर रहा हूँ डॉकर कंटेनर जीडीबी सेट किए गए ब्रेकपॉइंट्स को हिट नहीं करता है।

कदम पुन: पेश करने (सभी के टुकड़े कर रहे हैं रेडी कॉपी-पेस्ट)

एक डोकर फ़ाइल बनाएँ:

cat <<EOF> Dockerfile 
FROM ubuntu 
RUN apt-get update 
RUN apt-get install -y build-essential gdb 
EOF 

एक छवि निर्माण और उस में एक इंटरैक्टिव सत्र चलाएँ:

docker build -t gdb_problem_testing . && docker run --rm -it gdb_problem_testing bash 

कंटेनर के अंदर से छोटे main.cpp, संकलित करें और gdb चलाएं:

0 ,

GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 
[Skipped gdb greeting] 
Reading symbols from ./a.out...done. 
Breakpoint 1 at 0x40078c: file main.cpp, line 5. 
1 #include <iostream> 
2 
3 int main(int argc, const char *argv[]) 
4 { 
5  std::cout << "hi\n"; 
6  return 0; 
7 } 
Starting program: /a.out 
hi 
During startup program exited normally. 
(gdb) 

उत्पादन एक देख सकते हैं कि ब्रेकप्वाइंट नहीं मारा गया था से हालांकि कार्यक्रम मार डाला गया था (मुद्रित 'हाय') और सफलतापूर्वक बाहर निकल गया:

cat <<EOF > main.cpp && g++ -g main.cpp && gdb -ex 'break 5' -ex 'run' ./a.out 
#include <iostream> 

int main(int argc, const char *argv[]) 
{ 
    std::cout << "hi\n"; 
    return 0; 
} 
EOF 

gdb उत्पादन का निरीक्षण करें। मुझे लगता है कि यहां सबसे महत्वपूर्ण बात यह है कि कार्यक्रम चलाने की थी और संदेश स्टार्टअप कार्यक्रम के दौरान बाहर निकल गया है कि सामान्य रूप एक विषम व्यवहार (GDB ignores my breakpoints के अनुसार) है

प्रश्न

क्या सेट करने से रोक रहा है gdb ब्रेकपॉइंट और इसे कैसे ठीक किया जाए?

मैं क्या करने की कोशिश की अब तक

  1. के रूप में सुझाव दिया here, मैं /etc/apparmor.d/docker में एक लाइन बदलने की कोशिश की (मैं मेजबान में यह किया): profile docker-default flags=(attach_disconnected,mediate_deleted,complain) { द्वारा स्थानापन्न profile docker-default flags=(attach_disconnected,mediate_deleted) {। फिर डॉकर कंटेनर, संकलन, और जीडीबी चलाएं। नतीजा वही था: During startup program exited normally

  2. another answer में सुझाव के रूप में, कंटेनर का, मैं strace -f -o syscall.txt gdb ./a.out करने की कोशिश की, लेकिन मैं निम्नलिखित त्रुटि मिलती है:

    strace: test_ptrace_setoptions_followfork: PTRACE_TRACEME doesn't work: Permission denied 
    strace: test_ptrace_setoptions_followfork: unexpected exit status 1 
    

    लेकिन मैं कैसे आसपास इस काम करने के लिए समझ में नहीं आता। मैंने कंटेनर को रूट के रूप में शुरू करने का प्रयास किया: sudo docker run --rm -it gdb_problem_testing bash और फिर स्ट्रेस की कोशिश की - इससे मुझे एक ही त्रुटि मिली। मुझे स्वीकार करना होगा कि मुझे समझ में नहीं आता कि उपयोगकर्ता विशेषाधिकारों को डॉकर द्वारा कैसे प्रबंधित किया जाता है, यानी कंटेनर के अंदर रूट का अधिकार किस अधिकार का अधिकार रखता है और किसके पास यह अधिकार प्राप्त करता है (डॉकर डेमन से?)। चूंकि मैं ब्रेकपॉइंट पर हिट करने में सक्षम हूं, जब मैं मेजबान में जीडीबी चलाता हूं, तो मुझे संदेह है कि मेरी समस्या उपयोगकर्ता के अधिकारों को उबाल जाएगी, लेकिन मुझे नहीं पता कि इसे कैसे पहुंचाया जाए।

  3. मेजबान में मैंने echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope करने की कोशिश की, जैसा कि अभी तक another answer में सुझाया गया है।

+1

क्या आपके मेजबान ओएस (distro और कर्नेल संस्करण है)? हम त्रुटि को पुन: पेश करने का प्रयास कर सकते हैं। आपका उदाहरण ठीक काम करता है - जीडीबी सफलतापूर्वक लाइन 5 पर बंद हो जाता है - वेनिला पर, उबंटू 15.04 और 14.04.3 x86_64 के पूरी तरह से पैच किए गए संस्करण उबंटू 14.04.2 की डॉकर छवि का उपयोग करते हुए। –

+0

इसे आज़माने के लिए बहुत बहुत धन्यवाद। तथ्य यह है कि यह आपके लिए काम करता है, इस पर मुझे एक बिल्कुल अलग परिप्रेक्ष्य देता है। मेरा होस्ट ओएस उबंटू है। $ uname -a लिनक्स एलटी0377 3.19.0-42-जेनेरिक # 48 ~ 14.04.1-उबंटू एसएमपी शुक्र दिसंबर 18 10:24:49 यूटीसी 2015 x86_64 x86_64 x86_64 जीएनयू/लिनक्स। मुझे समझ में नहीं आता कि मेरे पास डॉकर छवि में उबंटू का कौन सा संस्करण है। अगर मैं कंटेनर के अंदर एकजुट हूं - मुझे होस्ट में समान आउटपुट मिलता है। –

+0

@ मार्कप्लॉटिक क्या आप मुझे बता सकते हैं कि आपका डॉकर संस्करण क्या है? –

उत्तर

18

tldr; का उपयोग

docker run --privileged 

लंबे समय तक: मैं कुछ problems with gdb in docker रहा था --- यह प्रयास किया गया था (और अनुत्तीर्ण) address space layout randomization निष्क्रिय करने के लिए --- लेकिन केवल docker-machine पर, मेरे देशी linux मेजबान पर नहीं।

जब gdb एएसएलआर को अक्षम करने में विफल रहा, तो मेरे सभी ब्रेकपॉइंट्स को अनदेखा कर दिया जाएगा। --privileged ध्वज का उपयोग करके मेरी समस्या तय की गई। आपकी माइलेज भिन्न हो सकती है।

+1

आपकी प्रतिक्रिया के लिए धन्यवाद! दुर्भाग्य से मैं अब इसका परीक्षण नहीं कर सकता, क्योंकि मेरे पास इस माहौल तक पहुंच नहीं है। अगर किसी और को आपका समाधान उपयोगी लगता है, तो मैं इसे एक उत्तर के रूप में स्वीकार करूंगा। –

+2

इससे मेरी मदद की। यह परेशान था कि क्यों कोई अंतराल नहीं मारा जा रहा है, लेकिन फिर कंटेनर के साथ चल रहा है - निजी काम किया! अब मैं अपने कंटेनर –

+1

के अंदर ठीक से जीडीबी का उपयोग कर सकता हूं इसने विंडोज़ पर मेरी समस्या हल की! –

1

@rubicks से उत्तर धन्यवाद।

और यदि आप --privileged विकल्प (उदाहरण के लिए आप बादल से एक कंटेनर का उपयोग कर रहे हैं) का उपयोग नहीं कर सकते हैं, तो आप अपने कार्यक्रम से स्टैकट्रेस मुद्रित कर सकते हैं:

How to automatically generate a stacktrace when my gcc C++ program crashes

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