2014年8月12日 星期二

因為返回值而造成執行的錯誤訊息 (c++)

git url https://github.com/descent/scheme_eval
git branch add
git commit: 254282e3336ed62010d0a62500aeb2d60665fd04

這篇要紀錄一個很奇怪的執行錯誤:

error message
 1 descent@debian-vm:scheme_eval$ ./s_eval 
 2 90> (+ 1 2)
 3 
 4 (+ , 1 , 2 , ) 
 5 in list
 6 in exp:1
 7 in exp:2
 8 in symbol:+
 9 apply:Symbol
10 
11 + , 
12 (1 , (2 , () ) ) 
13 num: 1
14 num: 2
15 sum: 3
16 *** Error in `./s_eval': free(): invalid pointer: 0xb75844a4 ***
17 ======= Backtrace: =========
18 /lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x75e72)[0xb744de72]
19 /lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x76bb0)[0xb744ebb0]
20 /usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb763099f]
21 /usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0xb7694cfb]
22 /usr/lib/i386-linux-gnu/libstdc++.so.6(+0x4665a)[0xb762e65a]
23 /usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSsD1Ev+0x2e)[0xb7694d5e]
24 ./s_eval[0x804c4b1]
25 ./s_eval[0x804ef5a]
26 ./s_eval[0x804e4f0]
27 ./s_eval[0x804dbfb]
28 ./s_eval[0x804d0e2]
29 ./s_eval[0x804c5c5]
30 ./s_eval[0x804c4a3]
31 ./s_eval[0x804b69e]
32 ./s_eval[0x804b8ef]
33 ./s_eval[0x804bc9d]
34 ./s_eval[0x804bd57]
35 /lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xf5)[0xb73f18f5]
36 ./s_eval[0x80493c1]
37 ======= Memory map: ========
38 08048000-08053000 r-xp 00000000 08:11 299681     /home/descent/git/scheme_eval/s_eval
39 08053000-08054000 rw-p 0000b000 08:11 299681     /home/descent/git/scheme_eval/s_eval
40 0940d000-0942e000 rw-p 00000000 00:00 0          [heap]
41 b73d6000-b73d8000 rw-p 00000000 00:00 0 
42 b73d8000-b7581000 r-xp 00000000 08:01 659097     /lib/i386-linux-gnu/i686/cmov/libc-2.17.so
43 b7581000-b7582000 ---p 001a9000 08:01 659097     /lib/i386-linux-gnu/i686/cmov/libc-2.17.so
44 b7582000-b7584000 r--p 001a9000 08:01 659097     /lib/i386-linux-gnu/i686/cmov/libc-2.17.so
45 b7584000-b7585000 rw-p 001ab000 08:01 659097     /lib/i386-linux-gnu/i686/cmov/libc-2.17.so
46 b7585000-b7588000 rw-p 00000000 00:00 0 
47 b7588000-b75a3000 r-xp 00000000 08:01 659209     /lib/i386-linux-gnu/libgcc_s.so.1
48 b75a3000-b75a4000 rw-p 0001a000 08:01 659209     /lib/i386-linux-gnu/libgcc_s.so.1
49 b75a4000-b75a5000 rw-p 00000000 00:00 0 
50 b75a5000-b75e6000 r-xp 00000000 08:01 659084     /lib/i386-linux-gnu/i686/cmov/libm-2.17.so
51 b75e6000-b75e7000 r--p 00040000 08:01 659084     /lib/i386-linux-gnu/i686/cmov/libm-2.17.so
52 b75e7000-b75e8000 rw-p 00041000 08:01 659084     /lib/i386-linux-gnu/i686/cmov/libm-2.17.so
53 b75e8000-b76c4000 r-xp 00000000 08:01 558350     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19
54 b76c4000-b76c5000 ---p 000dc000 08:01 558350     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19
55 b76c5000-b76c9000 r--p 000dc000 08:01 558350     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19
56 b76c9000-b76ca000 rw-p 000e0000 08:01 558350     /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19
57 b76ca000-b76d1000 rw-p 00000000 00:00 0 
58 b76e7000-b76ec000 rw-p 00000000 00:00 0 
59 b76ec000-b76ed000 r-xp 00000000 00:00 0          [vdso]
60 b76ed000-b770c000 r-xp 00000000 08:01 659073     /lib/i386-linux-gnu/ld-2.17.so
61 b770c000-b770d000 r--p 0001f000 08:01 659073     /lib/i386-linux-gnu/ld-2.17.so
62 b770d000-b770e000 rw-p 00020000 08:01 659073     /lib/i386-linux-gnu/ld-2.17.so
63 bfc50000-bfc71000 rw-p 00000000 00:00 0          [stack]
64 Aborted

程式在執行後吐出 L16 之後的錯誤訊息, 真是令人害怕。出問題的程式碼在下面:

s_eval.cpp
156 cell proc_add(const cell &c)
157 {
158   int sum = add_cell(c);
159   cout << "sum: " << sum << endl;
160   cell(Number, str(sum)); // should return cell
161 }


396 cell apply(const cell &func, const cell &args)
397 {
398   cout << "apply:" << func.kind_str() << endl;
399   cout << endl;
400   print_cell(func);
401   cout << endl;
402   print_cell(args);
403   cout << endl;
404 
405   if (func.kind() != Proc)
406   {
407     // func.proc(args);
408   }
409   proc_add(args);
410  
411 
412   return func;
413 }

L160 沒有正確 return cell 就引發這錯誤, 實在令我驚訝, L409 呼叫 proc_add 後, 我也沒有用到 return 的 cell, 就算我沒在 proc_add return cell, 應該也不會有錯阿, 我是這麼想的。

一定有程式碼執行了什麼才引發這錯誤, 雖然我沒使用回傳的 cell object, 但是 c++ compiler 幫我們安插了 destructor, 應該是在執行這個 destructor 時發生錯誤的。

c++ code
1 sh-4.2$ c++filt _ZNSsD1Ev
2 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()

有發動 std::string destructor 但是該位址上的東西不是可以正常執行的, 因為我沒 return cell, 那個空間是未知程式碼, 所以就造成這可怕的結果。

我沒有反組譯來證明, 這是冥想出來的。歡迎有其他想法的朋友一起討論。

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。