执行 malloc() 期间的 EXC_BAD_ACCESS (KERN_INVALID_ADDRESS)
我正在 Mac OS X Snow Leopard 中使用以下 GCC 编译 C 库:
Diderot:~ brandizzi$ gcc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~6/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)
当我运行该库的一些单元测试时(写在 CuTest)其中一项测试遇到了问题:EXC_BAD_ACCESS
信号。这是一个常见的问题,我对此类问题有一些了解 - 我是一个 Linux 人员,将其称为“分段错误”,了解发生了什么以及解决问题的常用方法。令人惊讶的是,错误的访问是在 malloc
函数的执行过程中执行的。看看我在 GDB 中得到的回溯:
(gdb) bt
#0 0x00007fff89000a34 in tiny_free_list_add_ptr ()
#1 0x00007fff88ffe147 in tiny_malloc_from_free_list ()
#2 0x00007fff88ffcfdd in szone_malloc_should_clear ()
#3 0x00007fff88ffceaa in malloc_zone_malloc ()
#4 0x00007fff88ffb1a8 in malloc ()
#5 0x0000000100008c72 in util_copy_string (string=0x100008e48 "libsecretary") at src/util.c:7
#6 0x0000000100008126 in project_new (name=0x100008e48 "libsecretary") at src/project.c:8
#7 0x00000001000078b9 in secretary_start (secretary=0x10080b000, name=0x100008e48 "libsecretary") at src/secretary.c:23
#8 0x00000001000020f8 in test_secretary_move_task_from_project_to_project (test=0x1001005b0) at src/test/secretary.c:146
#9 0x0000000100006eae in CuTestRun (tc=0x1001005b0) at cutest/CuTest.c:143
#10 0x00000001000075c1 in CuSuiteRun (testSuite=0x100800000) at cutest/CuTest.c:289
#11 0x0000000100001527 in RunAllTests () at src/test/run_all.c:22
#12 0x000000010000156b in main () at src/test/run_all.c:32
这个测试用例有以下几行,错误总是发生在第四行。如果我以任何方式切换线路,问题仍然会发生在第四个线路上:
Secretary *secretary = secretary_new();
Task *task = secretary_appoint(secretary, "Test task transference");
Project *destination = secretary_start(secretary, "Chocrotary");
Project *origin = secretary_start(secretary, "libsecretary");
那么,malloc()
是如何导致这样的问题的呢?我什至没有传递指向它的指针!这是一个错误吗?有人见过这样的东西吗?
提前致谢!
I am compiling a C library in Mac OS X Snow Leopard with the folloing GCC:
Diderot:~ brandizzi$ gcc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~6/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)
When I run some unit tests of this library (which are written on CuTest) one of the tests got a problem: an EXC_BAD_ACCESS
signal. That is a usual problem and I have some understanding about this kind of issue - I'm a Linux guy who called it "Segmentation fault", understand what is happening and the usual ways to solve the problem. What is amazing is that the bad access is executed inside the execution of malloc
function. Look at this backtrace I've got in GDB:
(gdb) bt
#0 0x00007fff89000a34 in tiny_free_list_add_ptr ()
#1 0x00007fff88ffe147 in tiny_malloc_from_free_list ()
#2 0x00007fff88ffcfdd in szone_malloc_should_clear ()
#3 0x00007fff88ffceaa in malloc_zone_malloc ()
#4 0x00007fff88ffb1a8 in malloc ()
#5 0x0000000100008c72 in util_copy_string (string=0x100008e48 "libsecretary") at src/util.c:7
#6 0x0000000100008126 in project_new (name=0x100008e48 "libsecretary") at src/project.c:8
#7 0x00000001000078b9 in secretary_start (secretary=0x10080b000, name=0x100008e48 "libsecretary") at src/secretary.c:23
#8 0x00000001000020f8 in test_secretary_move_task_from_project_to_project (test=0x1001005b0) at src/test/secretary.c:146
#9 0x0000000100006eae in CuTestRun (tc=0x1001005b0) at cutest/CuTest.c:143
#10 0x00000001000075c1 in CuSuiteRun (testSuite=0x100800000) at cutest/CuTest.c:289
#11 0x0000000100001527 in RunAllTests () at src/test/run_all.c:22
#12 0x000000010000156b in main () at src/test/run_all.c:32
This test case has the following lines, and the error always happens at the fourth one. If I switch the lines in any way, the problem still happens at the fourth one:
Secretary *secretary = secretary_new();
Task *task = secretary_appoint(secretary, "Test task transference");
Project *destination = secretary_start(secretary, "Chocrotary");
Project *origin = secretary_start(secretary, "libsecretary");
So, how can malloc()
cause such problem? I do not even pass a pointer to it! Is it a bug? Has someone seen something like this?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最有可能的是,程序执行早期的某些操作正在写入它无权写入的内存,从而破坏了堆的数据结构。然后,稍后,
malloc
被调用,并尝试跟踪一个被无意义覆盖的指针(或通过被无意义覆盖的值或其他内容索引某些内容),然后繁荣。您可能想尝试在
valgrind
下运行测试套件,看看哪里首先出现问题。Most likely, something earlier in the program's execution is writing to memory it isn't entitled to, corrupting the heap's data structures. Then, later,
malloc
gets called and tries to follow a pointer that's been overwritten with nonsense (or index something via a value that's being overwritten with nonsense, or whatever), and boom.You might want to try running your test suite under
valgrind
to see where things first start going wrong.这个问题有很多原因:没有分配内存,指针指向错误的位置等等。
在我的例子中,我分配了一个数组,例如
Project
与 < code>MAX_PROJECT_COUNT 个职位。我写了,但它没有考虑
Project
结构的大小!正确的解决方案是注意,但是,您的问题可能有很大不同,因此不可能应用相同的解决方案。
There is an awful lot of reasons for this problem: one did not allocate the memory, the pointer points to the wrong place etc. etc.
In my case, I was allocating an array of e.g.
Project
withMAX_PROJECT_COUNT
positions. I wrotebut it does not consider the size of the
Project
struct! The correct solution would beNote, however, that your problem may be considerably different so it is not possible to apply the same solution.