टोडी मैंने उबंटू 10.04 एलटीएस से उबंटू 12.04 एलटीएस (या ghc 6.12.1
से ghc 7.4.1
) में अपनी विकासशील मशीन अपडेट की और मैं अपने धारावाहिक परियोजना में एक बहुत ही अजीब व्यवहार में भाग गया।जीएचसी: अजीब परिस्थितियों में सेगमेंटेशन गलती
कुछ घंटे के बाद, मैं इसे निम्नलिखित कोड करने के लिए कम:
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Data.Word
import Text.Printf
import Foreign
foreign import ccall "dynamic"
code_void :: FunPtr (IO()) -> (IO())
main :: IO()
main = do
entryPtr <- (mallocBytes 2)
poke entryPtr (0xc390 :: Word16) -- nop (0x90); ret(0xc3) (little endian order)
_ <- printf "entry point: 0x%08x\n" ((fromIntegral $ ptrToIntPtr entryPtr) :: Int)
_ <- getLine -- for debugging
code_void $ castPtrToFunPtr entryPtr
putStrLn "welcome back"
मैं, रन-टाइम में कुछ कोड उत्पन्न इसे करने के लिए कूद, और फिर से वापस आने के लिए कोशिश कर रहा हूँ। , अगर मैं खोल से सीधे द्विआधारी फोन
$ make
ghc --make -Wall -O2 Main.hs -o stackoverflow_segv
[1 of 1] Compiling Main (Main.hs, Main.o)
Linking stackoverflow_segv ...
./stackoverflow_segv
entry point: 0x098d77e0
welcome back
हालांकि: एक Makefile का उपयोग करना, सब कुछ ठीक है (? सौभाग्य से)
$ ./stackoverflow_segv
entry point: 0x092547e0
Segmentation fault (core dumped)
यह व्यवहार प्रतिलिपि प्रस्तुत करने योग्य है।
का उपयोग gdb
, objdump
और /proc
मैं पता लगा:
$ gdb -q stackoverflow_segv
Reading symbols from /home/lewurm/stackoverflow/stackoverflow_segv...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/lewurm/stackoverflow/stackoverflow_segv
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
entry point: 0x080fc810
दबाने में प्रवेश करने से पहले, मैं एक दूसरे टर्मिनल के लिए स्विच:
$ cat /proc/`pgrep stackoverflow`/maps
[...]
08048000-080ea000 r-xp 00000000 08:01 2492678 /home/lewurm/stackoverflow/stackoverflow_segv
080ea000-080eb000 r--p 000a2000 08:01 2492678 /home/lewurm/stackoverflow/stackoverflow_segv
080eb000-080f1000 rw-p 000a3000 08:01 2492678 /home/lewurm/stackoverflow/stackoverflow_segv
080f1000-08115000 rw-p 00000000 00:00 0 [heap]
[...]
और फिर से वापस:
<enter>
Program received signal SIGSEGV, Segmentation fault.
0x0804ce3c in s2aV_info()
बू। चलो देखते हैं क्या इस कोड को करता है:
$ objdump -D stackoverflow_segv | grep -C 3 804ce3c
804ce31: 89 44 24 4c mov %eax,0x4c(%esp)
804ce35: 83 ec 0c sub $0xc,%esp
804ce38: 8b 44 24 4c mov 0x4c(%esp),%eax
804ce3c: ff d0 call *%eax
804ce3e: 83 c4 0c add $0xc,%esp
804ce41: 83 ec 08 sub $0x8,%esp
804ce44: 8b 44 24 54 mov 0x54(%esp),%eax
Uhm, *%eax
पर कूद। %eax
फिर से क्या था?
(gdb) info reg eax
eax 0x80fc810 135251984
ठीक है, वास्तव में यह केवल कोड बफर है। /proc/*/maps
देखकर हमें बताता है कि यह पृष्ठ निष्पादन योग्य नहीं है (rw-p
, है ना?)। लेकिन, यह उसी स्थिति में है जब इसे make
के भीतर निष्पादित किया जाता है।
यहां क्या गलत है?
btw, कोड भी माध्यम से gist
संपादित करें उपलब्ध है: ghc bug report
यहां कमांड लाइन से ठीक काम करता है (openSUSE 11.4, x86_64)। उबंटू की गलती हो सकती है? यदि आपके पास समय है तो स्वयं निर्मित जीएचसी के साथ प्रयास करें। –
आपके उत्तर के लिए धन्यवाद! मैंने इसे [haskell.org] (http://www.haskell.org/ghc) से बाइनरी पैकेज के साथ करने की कोशिश की: (1) ghc-7.4.1, अभी भी वही समस्या है। (2) ghc-7.2.2 अब और नहीं \ अच्छा/अच्छा! (3) ghc-6.12.1 इसी प्रकार। क्या आपको लगता है कि मुझे जीएचसी लोगों में एक बग के रूप में रिपोर्ट करनी चाहिए? – lewurm
वेनिला बाइनरी (अज्ञात-लिनक्स)? यदि मैं 7.4.1 के बजाय 7.2.2 का उपयोग करता हूं, तो मुझे वही व्यवहार मिलता है। वास्तव में अजीब। –