Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory 使用android ndk进行内存损坏调试_Memory_Memory Management_Android Ndk - Fatal编程技术网

Memory 使用android ndk进行内存损坏调试

Memory 使用android ndk进行内存损坏调试,memory,memory-management,android-ndk,Memory,Memory Management,Android Ndk,当一个void函数返回给它的调用者时,我的android应用程序的本机部分出现了一个segfault。为了更好地可视化,我在被调用方函数的末尾放了一条log语句,在调用方函数中放了一条log语句,就在调用被调用方之后(很抱歉这个双关语)。 在logcat中,会打印第一条消息,而不会打印第二条消息(应用程序崩溃) 考虑到可能的内存损坏,我决定激活malloc调试(在adb shell中给出“setprop libc.debug.malloc 10”)。然后,在被调用函数末尾的日志消息之后,我在lo

当一个void函数返回给它的调用者时,我的android应用程序的本机部分出现了一个segfault。为了更好地可视化,我在被调用方函数的末尾放了一条log语句,在调用方函数中放了一条log语句,就在调用被调用方之后(很抱歉这个双关语)。 在logcat中,会打印第一条消息,而不会打印第二条消息(应用程序崩溃)

考虑到可能的内存损坏,我决定激活malloc调试(在adb shell中给出“setprop libc.debug.malloc 10”)。然后,在被调用函数末尾的日志消息之后,我在logcat中得到了以下信息:

D/MyApp - NativeSide(12778):  I am the callee function and I am about to return!
E/libc    (12778): *** FREE CHECK: buffer 0x82869900 corrupted 16 bytes before allocation
E/libc    (12778): call stack:
E/libc    (12778):  0: 8000e3ea
E/libc    (12778):  1: 8000e49c
E/libc    (12778):  2: 8000e4e2
E/libc    (12778):  3: 8000e540
E/libc    (12778):  4: afd14ccc
E/libc    (12778):  5: 81258188
E/libc    (12778):  6: 81258188
E/libc    (12778):  7: 81258188
E/libc    (12778):  8: 81258188
E/libc    (12778):  9: 81258188
E/libc    (12778): 10: 81258188
E/libc    (12778): 11: 81258188
E/libc    (12778): 12: 81258188
E/libc    (12778): 13: 81258188
E/libc    (12778): 14: 81258188
E/libc    (12778): 15: 81258188
E/libc    (12778): 16: 81258188
E/libc    (12778): 17: 81258188
E/libc    (12778): 18: 81258188
E/libc    (12778): 19: 81258188
我找不到有关如何破译此输出的任何信息。每一行显示的数字在每次应用程序发布时都会发生变化。我希望有一种方法可以将这些信息作为腐败发生的线索,因为我无法从代码中找到它。我还尝试使用“-fstack check”标志构建本机库,但我不能说我是否在日志中获得了更多信息(似乎没有,但我可能错过了),或者我是否需要做其他事情来获得它们

另外,这里是堆栈转储,在“FREE CHECK:”消息之后

I/DEBUG(12311):************************************
I/DEBUG(12311):构建指纹:“google/soju/crespo:2.3/GRH55/79397:用户/发布密钥”

I/DEBUG(12311):pid:12778,tid:12907>>>com.ntrack.tunermalloc DEBUG属性可能在您分配的区域前后设置了一些幻数。然后,在释放时,它会检查这些区域以确保幻数仍然存在

例如,如果分配1024字节:

char * p = malloc(1024);
malloc调试代码实际上会分配您请求的1024个字节,外加一些额外的字节:

[ 32 bytes ---- | -------- 1024 bytes ------| ---- 32 bytes ]
^ 0xc0000000    ^ 0xc0000020
然后,库会将一个神奇的值写入这32个字节:

[ 32 bytes ---- | -------- 1024 bytes ------| ---- 32 bytes ]
[  0xdeadd00d   |                           | 0xdeadd00d    ]
^ 0xc0000000    ^ 0xc0000020
库将
0xc000020
返回到
p
中,并在内部保存
0xc000000
、大小等。 然后,您的函数以某种方式使用分配的区域:

memset(p, 0, 1025);
请注意,此行复制了超过1024个字节。这会将0写入最后32个字节的魔法区域(请注意最后32个字节中的
0
,应该是
0xdeadd00d
):

当函数调用free时:

free(p);
然后,库将进行检查,以确保第一个和最后32个字节仍然是
0xdeadd00d
。由于函数重写了最后32个字节,它将打印一个错误,就像您发布的一样

这只是malloc调试检查如何工作的一个示例。如果您想确切了解malloc调试检查的内容及其工作方式,请转到Android source的
bionic
目录,搜索您设置的属性,
libc.debug.malloc

检查代码,了解如何在被调用函数中使用分配的内存。您可能正在向分配区域之外的区域写入内容。

对我来说,这是:

在我的android应用程序的本机部分,当一个void函数返回到它的调用者时,出现了一个segfault

表示堆栈损坏(比堆损坏更严重)。您从中返回的函数(以及从它调用的每个函数中返回的函数)的堆栈上存储了什么状态

您看到的调用堆栈输出应该是检测到损坏时堆栈上每个函数的地址。您需要知道加载库的地址,才能将这些地址映射回
中的符号。因此
(我认为这个问题会有所帮助:)


81258188
在堆栈转储的顶部重复的事实也表明您可能已经破坏了堆栈的底部(通过多次递归)。如果您不知道代码中存在任何有意的递归,那么找出库的加载位置并将其映射回代码可能会很有用。

这将是大量代码:)谢谢大家的回答。在更改了之前调用的函数中的内容后,问题昨天就解决了,这影响了在某种程度上,我还没有完全理解错误函数,但我也认为它与堆栈损坏有关,因为——正如你所猜测的——函数中有一个递归部分,应该进行更深入的研究。我一检查就会回到这个问题上来。谢谢你!我犯的错误是——我想记住r一个包含100个uint32_t的数组。我调用了memAlloc(100),并使用长度为0->99的for循环写入该数组。它肯定会抛出此错误,因为我写入的内容超出了我分配的范围!memAlloc(100*sizeof(uin32_t))修复了它。希望这对某人有所帮助!
[ 32 bytes ---- | -------- 1024 bytes ------| ---- 32 bytes ]
[  0xdeadd00d   |  000...             ...00 | 0x0eadd00d    ]
^ 0xc0000000    ^ 0xc0000020  (address)
free(p);