我有一個分段錯誤,對我沒有任何意義。 第538次調用這個函數時,它失敗了,但是我看不到任何參數的錯誤 。我可以輸入相同的表達式gdb ,它會很樂意做到這一點沒有抱怨。我甚至利用 si匆匆看過它,看着寄存器,但它仍然沒有任何意義。 我該如何着手解決這個問題?沒有明顯原因的分段錯誤
一個奇怪的是,gdb報告「bit」參數 在故障時從0更改爲1。 我想「位」是在一個註冊表中被重用的東西。
我也試過這個沒有優化。涉及更多指令 ,但結果相同。
請注意,我使用gdb訪問代碼即將訪問的相同位置,但沒有任何問題。
代碼:
void Bits::set(int bit)
{
if (bit >= _size*16) BUG;
_dat[bit/16] |= 1 << (bit & 15);
}
GDB運行:
Breakpoint 1, Bits::set (this=0x68374, bit=0) at util.cpp:181
181 _dat[bit/16] |= 1 << (bit & 15);
1: x/i $pc
=> 0x3964c <_ZN4Bits3setEi+36>: ldr r3, [r0, #4]
(gdb) si
0x00039650 181 _dat[bit/16] |= 1 << (bit & 15);
1: x/i $pc
=> 0x39650 <_ZN4Bits3setEi+40>: mov r1, #1
(gdb)
0x00039654 181 _dat[bit/16] |= 1 << (bit & 15);
1: x/i $pc
=> 0x39654 <_ZN4Bits3setEi+44>: ldrh r2, [r12, r3]
(gdb)
0x00039658 181 _dat[bit/16] |= 1 << (bit & 15);
1: x/i $pc
=> 0x39658 <_ZN4Bits3setEi+48>: orr r2, r2, r1, lsl lr
(gdb)
0x0003965c 181 _dat[bit/16] |= 1 << (bit & 15);
1: x/i $pc
=> 0x3965c <_ZN4Bits3setEi+52>: strh r2, [r12, r3]
(gdb) p _dat
$18 = (short *) 0x4ee74
(gdb) p *_dat
$19 = -3784
(gdb) p $r2
$20 = 61753
(gdb) p $r12
$21 = 0
(gdb) p/x $r3
$22 = 0x4ee74
(gdb) si
Program received signal SIGSEGV, Segmentation fault.
0x0003965c in Bits::set (this=0x68374, bit=1) at util.cpp:181
181 _dat[bit/16] |= 1 << (bit & 15);
1: x/i $pc
=> 0x3965c <_ZN4Bits3setEi+52>: strh r2, [r12, r3]
(gdb)
順便說一句,我使用gdbserver的位置。這裏的目標響應:
50:/mnt/home/rw # ./gdbserver x:12 cx Andersen_Studio.cxc
Process cx created; pid = 226
Listening on port 12
Remote debugging from host 192.168.1.40
pc : [<0003965c>] lr : [<00000000>] Tainted: P
sp : 7ffffdb4 ip : 00000000 fp : 7ffffe84
r10: 2ada7884 r9 : 0000c6c8 r8 : 2ada8d28
r7 : 00000002 r6 : 0005c0b8 r5 : 00000000 r4 : 0006dc10
r3 : 0004ee74 r2 : 0000f139 r1 : 00000001 r0 : 00068374
Flags: Nzcv IRQs on FIQs on Mode USER_32 Segment user
Control: C000317F Table: 017EC000 DAC: 00000015
更多信息:如果我做手工的命令,故障不會發生:
Breakpoint 1, Bits::set (this=0x6c75c, bit=0) at util.cpp:181
181 _dat[bit/16] |= 1 << (bit & 15);
(gdb) c 538
Will ignore next 537 crossings of breakpoint 1. Continuing.
Breakpoint 1, Bits::set (this=0x68374, bit=0) at util.cpp:181
181 _dat[bit/16] |= 1 << (bit & 15);
(gdb) p _dat[bit/16] |= 1 << (bit & 15)
$25 = -3783
(gdb) dis 1
(gdb) c
Continuing.
只是引用_dat [0]沒有幫助,但例如鍵入_dat [0] = 0確實可以避免這個問題。
(編輯後)
如果我們要尋找在該函數生成的代碼,我決定關閉優化。這裏是未優化的代碼:
(gdb) disass
Dump of assembler code for function _ZN4Bits3setEi:
0x0006a1d8 <+0>: mov r12, sp
0x0006a1dc <+4>: push {r11, r12, lr, pc}
0x0006a1e0 <+8>: sub r11, r12, #4
0x0006a1e4 <+12>: sub sp, sp, #8
0x0006a1e8 <+16>: str r0, [r11, #-16]
0x0006a1ec <+20>: str r1, [r11, #-20]
=> 0x0006a1f0 <+24>: ldr r3, [r11, #-16]
0x0006a1f4 <+28>: ldr r3, [r3]
0x0006a1f8 <+32>: lsl r2, r3, #4
0x0006a1fc <+36>: ldr r3, [r11, #-20]
0x0006a200 <+40>: cmp r3, r2
0x0006a204 <+44>: blt 0x6a220 <_ZN4Bits3setEi+72>
0x0006a208 <+48>: ldr r0, [pc, #108] ; 0x6a27c <_ZN4Bits3setEi+164>
0x0006a20c <+52>: ldr r1, [pc, #108] ; 0x6a280 <_ZN4Bits3setEi+168>
0x0006a210 <+56>: mov r2, #180 ; 0xb4
0x0006a214 <+60>: bl 0xa00c <printf>
0x0006a218 <+64>: mov r0, #1
0x0006a21c <+68>: bl 0xa09c <exit>
0x0006a220 <+72>: ldr r1, [r11, #-16]
0x0006a224 <+76>: ldr r2, [r11, #-20]
0x0006a228 <+80>: asr r3, r2, #31
0x0006a22c <+84>: lsr r3, r3, #28
0x0006a230 <+88>: add r3, r2, r3
0x0006a234 <+92>: asr r0, r3, #4
0x0006a238 <+96>: mov r3, r0
0x0006a23c <+100>: lsl r2, r3, #1
0x0006a240 <+104>: ldr r3, [r1, #4]
0x0006a244 <+108>: add r12, r2, r3
0x0006a248 <+112>: ldr r1, [r11, #-16]
0x0006a24c <+116>: mov r3, r0
0x0006a250 <+120>: lsl r2, r3, #1
0x0006a254 <+124>: ldr r3, [r1, #4]
0x0006a258 <+128>: add r1, r2, r3
0x0006a25c <+132>: ldr r3, [r11, #-20]
0x0006a260 <+136>: and r2, r3, #15
0x0006a264 <+140>: mov r3, #1
0x0006a268 <+144>: lsl r3, r3, r2
0x0006a26c <+148>: ldrh r2, [r1]
0x0006a270 <+152>: orr r3, r2, r3
0x0006a274 <+156>: strh r3, [r12]
0x0006a278 <+160>: ldmdb r11, {r11, sp, pc}
0x0006a27c <+164>: andeq r8, r8, r0, lsr r12
0x0006a280 <+168>: andeq r8, r8, r4, asr r12
End of assembler dump.
(gdb)
我試着插入_dat [0] = 0;在「壞」聲明之前,並且導致錯誤。 我試過_dat [0] ++;那也是錯誤的。
所以你說執行ARM彙編指令'strh r2,[r12,r3]'會導致訪問衝突。問:是0x4ee74(包含在r3中)有效嗎? – paulsm4 2013-04-06 17:55:19
0x4ee74有效。請參閱gdb響應$ 19。 – rich 2013-04-06 17:59:46
'_size'的價值是什麼?我沒有看到任何明顯的錯誤。你在使用glibc嗎?可能值得導出'MALLOC_CHECK_ = 3'來讓glibc檢查malloc相關的問題。 – jszakmeister 2013-04-06 18:46:13