मेरा segmentation error कहाँ गायब हो गया?
(rmpr.xyz)entrसे C प्रोग्राम को बार-बार compile और run करने परhelloअसामान्य रूप से बंद हुआ, लेकिन compile output के बादSegmentation faultसंदेश दिखाई नहीं दिया- यह संदेश crash हुए प्रोग्राम से नहीं, बल्कि child process को reap करते समय
SIGSEGVसे termination की पुष्टि करने वाले parent shell द्वारा प्रिंट किया जाता है bash -cको स्पष्ट रूप से लिखने पर भी, अगर वास्तव में चलाने के लिए सिर्फ वही एक कमांड बची हो, तो Bash नया process बनाने के बजायexecveसे खुद को replace कर सकता है, जिससे संदेश प्रिंट करने वाला parent shell गायब हो जाता है- अलग script में, shebang से शुरू हुआ Bash
./helloको child के रूप में चलाकर उसका इंतज़ार करता है, इसलिएSIGSEGVकी पुष्टि करSegmentation fault (core dumped)प्रिंट करता है ./helloको subshell(./hello)में चलाने या उसके बाद; trueजोड़कर अगला काम बाकी रखने सेexecoptimization रुकती है और error message की पुष्टि की जा सकती है
संदेश गायब होने वाला execution path
-
नीचे दिए गए
entrकमांड सेhello.cबदलने पर हर बार compile और run दोहराया जाता हैls hello.c | entr -s "gcc -o hello hello.c && ./hello" -
hellosegmentation error के कारण बंद हो गया, लेकिनSegmentation faultसंदेश या दिखने वाला non-zero exit status के बिना कोई output नहीं बचा -
कमांड को
bash -cमें wrap करने पर भी नतीजा वही रहाls hello.c | entr -s "bash -c 'gcc -o hello hello.c && ./hello'" -
वहीं, वही कमांड
run.shमें ले जाकर चलाने पर error दिखता है#!/bin/bash gcc -o hello hello.c && ./hellols hello.c | entr -s ./run.sh ./run.sh: line 2: 104465 Segmentation fault (core dumped) ./hello -
Segmentation faultप्रिंट कौन करता है- crash हुआ प्रोग्राम पहले ही बंद हो चुका होता है, और parent shell child process को reap करते समय यह पुष्टि करने के बाद कि वह
SIGSEGVसे मरा, संदेश प्रिंट करता है - इसलिए यदि संदेश प्रिंट करने के लिए parent shell बचा ही न हो, तो कुछ भी दिखाई नहीं देता
bash -c "some_command"में यदि व्यवहारिक रूप से चलाने के लिए बस वही कमांड हो, तो Bash नया process fork किए बिनाexecveसे खुद को replace कर सकता है- यह optimization ज़्यादातर executions में बाहर से दिखाई नहीं देती
- script वाले तरीके में
entr./run.shको child के रूप में चलाता है, और shebang एक नया Bash शुरू करता है - नया Bash
gccचलाने के बाद./helloको fork करके उसका इंतज़ार करता है, इसलिए child केSIGSEGVtermination को देखकर error message छोड़ सकता है
- crash हुआ प्रोग्राम पहले ही बंद हो चुका होता है, और parent shell child process को reap करते समय यह पुष्टि करने के बाद कि वह
parent shell को बचाए रखने के दो तरीके
- crash होने वाली कमांड को subshell में चलाने पर संदेश फिर दिखाई देता है
ls hello.c | entr -s "gcc -o hello hello.c && (./hello)" hello.c: line 1: 106595 Segmentation fault (core dumped) ( ./hello )- parentheses यह मजबूर करते हैं कि
./hellofork किए गए subshell में चले - Bash parent की भूमिका बनाए रखता है, इसलिए वह subshell के
SIGSEGVtermination को reap करके संदेश प्रिंट कर सकता है
- parentheses यह मजबूर करते हैं कि
- crash वाली कमांड के बाद करने के लिए कोई काम छोड़ देने से भी
execoptimization रुक सकती हैls hello.c | entr -s "bash -c 'gcc -o hello hello.c && ./hello; true'" bash: line 1: 109516 Segmentation fault (core dumped) ./hello; trueकी वजह से./helloखत्म होने के बाद भी Bash के पास काम बचा रहता है, इसलिए वह खुद को उस प्रोग्राम से replace नहीं करता- अलग wrapper script के बिना भी segmentation error message की पुष्टि की जा सकती है
1 टिप्पणियां
Lobste.rs की राय
नए Linux distributions में अक्सर default रूप से core dump disable रहता है, जिससे परेशानी होती है
ulimit -c unlimitedसे इसे फिर enable किया जा सकता है, लेकिन लगता है core file executable के उसी directory में भी नहीं बनती, और systemd उसे कहीं और ले जाता हैOpenBSD की तरह core dump default रूप से enable हो और executable के उसी directory में रखा जाए तो अच्छा होगा, लेकिन अभी crash होने पर आम तौर पर executable को gdb के अंदर दोबारा चलाना पड़ता है
coredumpctlसे हाल के core dumps की list देखी और उन्हें निकाला जा सकता है/usr/binजैसी जगहों पर core dump ढूंढने का खयाल भी नहीं आएगा, और ऐसी locations अक्सर कम capacity वाले या read-only file system पर होती हैंdefault location के तौर पर working directory कहीं बेहतर नहीं होगी?
यहां तक कि user core files enable भी कर दे, तब भी मानो यह माना जाता है कि उसे पता नहीं कि वह क्या कर रहा है, इसलिए उन्हें ऐसी जगह छिपा दिया जाता है जिसे root के लिए भी ढूंढना मुश्किल हो
अगर C या D आदि में program लिखते समय आप जानना चाहते हैं कि वह क्यों terminate हुआ, तो
waitsystem call का return value check करना चाहिए; इससे पता चल सकता है कि program signal की वजह से terminate हुआ या नहींअगर operating system core dump को कहीं और forward करता है, तो ज़रूरत पड़ने पर तुरंत debugging करने या distribution को error report भेजने का फायदा भी मिलता है
Linux kernel core dump बनाते समय save location तय करने के लिए
/proc/sys/kernel/core_patternनाम की special file पढ़ता हैfile में लिखने के बजाय इसे किसी program को pipe भी किया जा सकता है, जिससे GUI dialog दिखाना, debugger तुरंत launch करना, developer को report email करना जैसे काम संभव हैं
systemd kernel के
core_patternको अपने managed value पर set करता है, लेकिन systemd का इस्तेमाल न करने पर भी वही kernel feature इस्तेमाल किया जा सकता हैWindows XP के development के समय core dumps Microsoft को भेजकर ऐसे कई bugs fix किए गए जिनके अस्तित्व का भी शायद पता नहीं था; और Windows पर development tools install करने पर अपने programs develop करते समय on-demand debugger काफी उपयोगी होता है
यह feature 2003 में Linux में पेश किया गया था, और details
man 5 coreमें देखी जा सकती हैंCore dump debugging के लिए शानदार है, लेकिन अगर उसे असंबंधित-सी files के बगल में रख दिया जाए तो आम users confuse हो सकते हैं, और diagnostic reporting system के रूप में यह भयानक हो सकता है
submit किए गए Windows crash reports में कितना data जाता है, यह पहली बार देखकर मैं दंग रह गया था
अगर privacy की रक्षा करने वाले crash reporting system को आधार मानें, तो submitted crashes का diagnosis करने के लिए stack और register information भर से कारण infer करना सीखना होगा
यह बात मुझे बिल्कुल नहीं पता थी कि Bash कभी-कभी script के अंदर commands को सीधे
execकर देता है, और यह काफी हैरान करने वाला feature हैBash process खुद बहुत भारी भी नहीं होता, और जहां ज़रूरत होती है वहां आदतन
execइस्तेमाल कर लिया जाता है, इसलिए यह कुछ हद तक गलत design किया हुआ feature लगता हैहालांकि कुल execution counts मिलाकर देखें तो यह उम्मीद से बड़ा फर्क पैदा कर सकता है