最近team引入gcov来做代码分析。编译好的程序在Solaris上运行的好好的,结果在Linux上一运行就会产生core dump文件。这篇文章就介绍整个分析过程。
首先用gdb分析core文件,显示是strlen调用出了问题:
(gdb) #0 0x00000034e433386f in __strlen_sse42 () from /lib64/libc.so.6 #1 0x000000000053c57a in __gcov_init () #2 0x000000000053c4b9 in _GLOBAL__I_65535_0_g_cmd_param () at source/rerun/aicent_ara_rerun.c:963 #3 0x000000000053dc26 in __do_global_ctors_aux () #4 0x0000000000403743 in _init () #5 0x00007fff6d6b3ce8 in ?? () #6 0x000000000053db55 in __libc_csu_init () #7 0x00000034e421ecb0 in __libc_start_main () from /lib64/libc.so.6 #8 0x0000000000404449 in _start ()由于我们使用的gcc是用安装包形式安装的,没有源码。所以就从github上找了相应版本的gcc源代码,希望能有所帮助。以下是__gcov_init函数的代码(https://github.com/gcc-mirror/gcc/blob/gcc-4_4_7-release/gcc/libgcov.c):
void __gcov_init (struct gcov_info *info) { if (!info->version) return; if (gcov_version (info, info->version, 0)) { const char *ptr = info->filename; gcov_unsigned_t crc32 = gcov_crc32; size_t filename_length = strlen(info->filename); /* Refresh the longest file name information */ if (filename_length > gcov_max_filename) gcov_max_filename = filename_length; do { unsigned ix; gcov_unsigned_t value = *ptr << 24; for (ix = 8; ix--; value <<= 1) { gcov_unsigned_t feedback; feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0; crc32 <<= 1; crc32 ^= feedback; } } while (*ptr++); gcov_crc32 = crc32; if (!gcov_list) atexit (gcov_exit); info->next = gcov_list; gcov_list = info; } info->version = 0; }结合源代码和core文件可以看出,应该是“size_t filename_length = strlen(info->filename);”这一行出了问题。再结合汇编程序:
(gdb) disassemble __strlen_sse42 Dump of assembler code for function __strlen_sse42: 0x00000034e4333860 <+0>: pxor %xmm1,%xmm1 0x00000034e4333864 <+4>: mov