gdb coredump 调试
1.#设置core大小为无限
ulimit -c unlimited
2.#设置文件大小为无限
ulimit unlimited
3. ./a.out 产生core文件
4. gdb ./a.out core
5.bt 栈回溯,找到发生段错误的函数
#include
#include
#include
void func(void)
{
int * p = 0x0;
*p = 0x12345678;
}
int main(int argc, char const *argv[])
{
int a = 0;
int b = a;
int c = 0;
scanf("%d", &c);
if (c) {
}
else
func();
return 0;
}
步骤如下所示:
root@ubuntu:/home/share/c++_code# ./a.out
0
Segmentation fault (core dumped)
root@ubuntu:/home/share/c++_code# ls -l core
-rw------- 1 root root 208896 Sep 26 02:13 core
root@ubuntu:/home/share/c++_code#
root@ubuntu:/home/share/c++_code# gdb a.out core
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...(no debugging symbols found)...done.
[New LWP 10430]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0804844d in func ()
(gdb) bt
#0 0x0804844d in func ()
#1 0x08048497 in main ()
(gdb)
backtrace 调试 – 使用API的方式 (backtrace、backtrace_symbols)
#include
#include
#include
#include
#define SIZE 100
void backtrace_dump(void)
{
int j, nptrs;
void *buffer[100];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
would produce similar output to the following: */
strings = backtrace_symbols(buffer, nptrs);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
for (j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings);
}
static void seg_handler(int signo)
{
printf("recv signale %d\n", signo);
backtrace_dump();
exit(EXIT_FAILURE);
}
void func(void)
{
int * p = 0x0;
*p = 0x12345678;
}
int main(int argc, char const *argv[])
{
signal(SIGSEGV, seg_handler);
func();
return 0;
}
步骤如下所示:
可以看到段错误发生在:func+0x10这个地方,可以知道是挂在func函数里面
root@ubuntu:/home/share/c++_code# ./a.out
recv signale 11
backtrace() returned 7 addresses
./a.out(backtrace_dump+0x1f) [0x80487dc]
./a.out() [0x80488a5]
[0xb7746404]
./a.out(func+0x10) [0x80488c1]
./a.out(main+0x22) [0x80488eb]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0xb7598af3]
./a.out() [0x80486e1]
root@ubuntu:/home/share/c++_code#
backtrace 调试 – 不使用API的方式 ARM平台
#include
#include
#include
#include
#include
#include
#include
#include
/*
此结构体,在版本比较新的编译器中都有包含了,就不用再定义了
看实际情况而定
*/
typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Base address at which shared
object is loaded */
const char *dli_sname; /* Name of symbol whose definition
overlaps addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;
struct ucontext_ce123 {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */
}ucontext_ce123_;
struct sigframe_ce123 {
struct sigcontext sc;//保存一组寄存器上下文
unsigned long extramask[1];
unsigned long retcode;//保存返回地址
//struct aux_sigframe aux __attribute__((aligned(8)));
}sigframe_ce123;
int backtrace_ce123 (void **array, int size)
{
if (size <= 0)
return 0;
int *fp = 0, *next_fp = 0;
int cnt = 0;
int ret = 0;
__asm__(
"mov %0, fp\n"
: "=r"(fp)
);
array[cnt++] = (void *)(*(fp-1));
next_fp = (int *)(*(fp-3));
while((cnt <= size) && (next_fp != 0))
{
array[cnt++] = (void *)*(next_fp - 1);
next_fp = (int *)(*(next_fp-3));
}
ret = ((cnt <= size)?cnt:size);
printf("Backstrace (%d deep)\n", ret);
return ret;
}
char ** backtrace_symbols_ce123 (void *const *array, int size)
{
# define WORD_WIDTH 8
Dl_info info[size];
int status[size];
int cnt;
size_t total = 0;
char **result;
/* Fill in the information we can get from `dladdr'. */
for (cnt = 0; cnt < size; ++cnt)
{
status[cnt] = dladdr (array[cnt], &info[cnt]);
if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
/* We have some info, compute the length of the string which will be
"() [+offset]. */
total += (strlen (info[cnt].dli_fname ?: "")
+ (info[cnt].dli_sname ? strlen (info[cnt].dli_sname) + 3 + WORD_WIDTH + 3 : 1)
+ WORD_WIDTH + 5);
else
total += 5 + WORD_WIDTH;
}
/* Allocate memory for the result. */
result = (char **) malloc (size * sizeof (char *) + total);
if (result != NULL)
{
char *last = (char *) (result + size);
for (cnt = 0; cnt < size; ++cnt)
{
result[cnt] = last;
if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
{
char buf[20];
if (array[cnt] >= (void *) info[cnt].dli_saddr)
sprintf (buf, "+%#lx", \
(unsigned long)(array[cnt] - (unsigned long)(info[cnt].dli_saddr)));
else
sprintf (buf, "-%#lx", \
(unsigned long)(info[cnt].dli_saddr -(unsigned long)(array[cnt])));
last += 1 + sprintf (last, "%s%s%s%s%s[%p]",
info[cnt].dli_fname ?: "",
info[cnt].dli_sname ? "(" : "",
info[cnt].dli_sname ?: "",
info[cnt].dli_sname ? buf : "",
info[cnt].dli_sname ? ") " : " ",
array[cnt]);
}
else
last += 1 + sprintf (last, "[%p]", array[cnt]);
}
assert (last <= (char *) result + size * sizeof (char *) + total);
}
return result;
}
/* SIGSEGV信号的处理函数,回溯栈,打印函数的调用关系*/
void DebugBacktrace(unsigned int sn , siginfo_t *si , void *ptr)
{
/*int *ip = 0;
__asm__(
"mov %0, ip\n"
: "=r"(ip)
);
printf("sp = 0x%x\n", ip);
struct sigframe_ce123 * sigframe = (struct sigframe_ce123 * )ip;*/
if(NULL != ptr)
{
printf("\n\nunhandled page fault (%d) at: 0x%08x\n", si->si_signo,si->si_addr);
struct ucontext_ce123 *ucontext = (struct ucontext_ce123 *)ptr;
int pc = ucontext->uc_mcontext.arm_pc;
void *pc_array[1];
pc_array[0] = (void *)pc;
char **pc_name = backtrace_symbols_ce123(pc_array, 1);
printf("%d: %s\n", 0, *pc_name);
#define SIZE 100
void *array[SIZE];
int size, i;
char **strings;
size = backtrace_ce123(array, SIZE);
strings = backtrace_symbols_ce123(array, size);
for(i=0;i<size;i++)
printf("%d: %s\n", i+1, strings[i]);
free(strings);
}
else
printf("error!\n");
exit(-1);
}
void test_func(void)
{
int * p = 0x0;
*p = 0x12345678;
}
int main(int argc, char **argv)
{
struct sigaction s;
s.sa_flags = SA_SIGINFO;
s.sa_sigaction = (void (*)(int, siginfo_t*, void*))DebugBacktrace;
sigaction (SIGSEGV, &s, NULL);
test_func();
return 0;
}
部分资料来源于网络,若有侵权,请联系作者删除