在ARM(Raspbian)上,我正在使用我的应用程序接收SIGABRT
。从gdb
的回溯中我提取(主要)错误消息:realloc(): invalid next size
。
程序的数据结构非常复杂,但可以理解(非常简化),因为几个结构数组(不同类型的成员)一个接一个地直接分配(后来使用realloc()
按需动态调整大小)。
我认为(纠正我,如果你认为我错了)错误是由于部分代码写出一个数组的边界。但是,它偶然写入的内存被分配用于不同的数组。因此,代码不会收到SIGSEGV
。
array1
已分配为拥有1000名成员。
之后直接分配array2
也可以容纳1000名成员。
使用gdb
,我可以执行以下操作:
(gdb) print array1[999]
$1 = {count = 0, blockedcount = 0, domain = 0x0, wildcard = false}
(gdb) print array1[1000]
$2 = {count = 0, blockedcount = 249, domain = 0x166 <error: Cannot access memory at address 0x166>, wildcard = 32}
(gdb) print array1[1001]
$10 = {count = 1420597384, blockedcount = 1015, domain = 0x54acf6a0 "192.168.2.157", wildcard = 200}
可以看出,可以在1000
及以后访问该数组,尽管此内存从不分配给array1
,但是array2
(内部数据类型略有不同):
(gdb) print &array1[999]
$3 = (array1DataStruct *) 0x54acf170
(gdb) print &array1[1000]
$4 = (array1DataStruct *) 0x54acf180
(gdb) print &array2[0]
$5 = (array2DataStruct *) 0x54acf188
(gdb) print &array1[1001]
$6 = (array1DataStruct *) 0x54acf190
通过过大的array1
索引,我可以(愚蠢地)访问array2
中的内存。
问题:
是否有一种优雅的方式来检测&#34;超出阵列范围&#34;但是&#34;内部分配内存由整个程序&#34;使用一些简单的度量(如-fsanitize=address
之类的编译器标志)来访问错误?
不幸的是,似乎valgrind
无法对ARMv6硬件进行适当的分析:
disInstr(arm): unhandled instruction: 0xF1010200
cond=15(0xF) 27:20=16(0x10) 4:4=0 3:0=0(0x0)
==6318== valgrind: Unrecognised instruction at address 0x48426f4.
==6318== at 0x48426F4: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem.so)
==6318== Your program just tried to execute an instruction that Valgrind
==6318== did not recognise. There are two possible reasons for this.
==6318== 1. Your program has a bug and erroneously jumped to a non-code
==6318== location. If you are running Memcheck and you just saw a
==6318== warning about a bad jump, it's probably your program's fault.
==6318== 2. The instruction is legitimate but Valgrind doesn't handle it,
==6318== i.e. it's Valgrind's fault. If you think this is the case or
==6318== you are not sure, please let us know and we'll try to fix it.
==6318== Either way, Valgrind will now raise a SIGILL signal which will
==6318== probably kill your program.
==6318==
==6318== Process terminating with default action of signal 4 (SIGILL)
==6318== Illegal opcode at address 0x48426F4
==6318== at 0x48426F4: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem.so)