嵌入式设备存储和运行空间比较紧张,一般会对编译好的可执行文件进行strip操作,会丢失相应debug信息(一些符号表等),来减小文件大小。在没有debug信息时,gdb很难定位到出错的位置。
一、可执行文件说明
如图是strip前的文件信息 readelf -S hello
文件大小:
strip后,包含很多debug信息section被删除,相应的文件大小也变小了
在使用gdb调试时,看不到出问题的具体位置,大部分可能函数名称都看不到
二、导出符号表
在strip前导出符号表,当strip后的程序出现问题时,通过导出来的符号表完成问题定位。
下文中 / … / 代表省略的目录路径。
原文件大小
1、导出符号表
/ … /mips-linux-objcopy --only-keep-debug hello hello.debug
2、strip程序
/ … /mips-linux-strip hello
strip之后的大小
3、将第1步中的符号hello.debug和程序重新组合
/ … /mips-linux-objcopy --add-gnu-debuglink=hello.debug hello
可以看到,这样处理完,文件大小没有增加多少。
4、验证是否可以通过coredump文件定位到debug信息。
如图可以查看到调试信息。为了方便,执行gdb时,需要coredump文件,可执行文件,hello.debug在同一个目录。
/ … /mips-linux-gdb hello core-hello-3502-946689814-11
三、编译说明
1、GCC需要添加-g选项
2、Makefile可以按如图方式处理文件
四、如何打开coredump
1、在linux kernel中打开ELF_CORE开关,重新编译烧写内核
->[Config Kernel settings]
-> [General setup]
-> [Configure standard kernel features(except users)]
-> [Enable ELF core dumps]
2、设置coredump文件大小
2.1 使用ulimit -c unlimited设置大小为unlimited
2.2 或者程序中使用setrlimit设置代码
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#define SYSTEM_CORE_DUMP_FILE_PATH ("/tmp")
void system_init_core_dump(void)
{
struct stat st;
struct rlimit limit;
char core_pattern[256] = {0};
char buf[256] = {0};
if(0 != stat(SYSTEM_CORE_DUMP_FILE_PATH, &st))
{
printf("path %s is invaild.\r\n", SYSTEM_CORE_DUMP_FILE_PATH);
return;
}
snprintf(core_pattern, sizeof(core_pattern), "%s%s", SYSTEM_CORE_DUMP_FILE_PATH, "/core-%e-%p-%t-%s");
memset(&limit, 0x0, sizeof(struct rlimit));
if (0 == getrlimit(RLIMIT_CORE, &limit))
{
printf("rlim_cur = %lld, rlim_max = %lld.\r\n", limit.rlim_cur, limit.rlim_max);
}
memset(&limit, 0x0, sizeof(struct rlimit));
limit.rlim_cur = RLIM_INFINITY;
limit.rlim_max = RLIM_INFINITY;
if (0 == setrlimit(RLIMIT_CORE, &limit))
{
printf("setrlimit core dump success.\r\n");
snprintf(buf, 256, "echo %s > /proc/sys/kernel/core_pattern", core_pattern);
system(buf);
}
else
{
printf("setrlimit core dump failed.\r\n");
}
memset(&limit, 0x0, sizeof(struct rlimit));
if (0 == getrlimit(RLIMIT_CORE, &limit))
{
printf("now rlim_cur = %lld, rlim_max = %lld.\r\n", limit.rlim_cur, limit.rlim_max);
}
return;
}