标签:linux内核 linux c语言 debug callback
A backtrace is the series of currently active function calls for the program.
#include <execinfo.h> int backtrace(void **buffer, int size); char **backtrace_symbols(void *const *buffer, int size); void backtrace_symbols_fd(void *const *buffer, int size, int fd);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <execinfo.h>
#define SIZE (100)
static sigset_t signals_handled;
static void dbg_backtrace(void)
{
int i, nline;
void *buffer[SIZE];
char **strings;
nline = backtrace(buffer, SIZE);
printf("addr: %d = backtrace()\n", nline);
strings = backtrace_symbols(buffer, nline);
if (NULL == strings) {
perror("backtrace_symbols()\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < nline; i ++) {
printf("callback: %s\n", strings[j]);
}
/* backtrace_symbols() 内部有调用malloc函数 */
free(strings);
}
static void sig_handler_hup(int sig)
{
printf("%s() %d\n\n", __func__, sig);
}
static void sig_handler_debug(int sig)
{
printf("%s() %d\n\n", __func__, sig);
}
static void sig_handler_usr2(int sig)
{
printf("%s() %d\n\n", __func__, sig);
}
static void sig_handler_fatal(int sig)
{
printf("Fatal signal %d\n\n", sig);
dbg_backtrace();
exit(127);
}
void signals_setup(void)
{
struct sigaction sa;
sigemptyset(&signals_handled);
sigaddset(&signals_handled, SIGHUP);
sigaddset(&signals_handled, SIGINT);
sigaddset(&signals_handled, SIGTERM);
sigaddset(&signals_handled, SIGUSR2);
#define SIGNAL(s, handler) do { sa.sa_handler = handler; if (sigaction(s, &sa, NULL) < 0) printf("could not set signal handler (%d): %m", s); } while(0);
sa.sa_mask = signals_handled;
sa.sa_flags = 0;
SIGNAL(SIGHUP, sig_handler_hup);
SIGNAL(SIGUSR1, sig_handler_debug);
SIGNAL(SIGUSR2, sig_handler_usr2);
SIGNAL(SIGABRT, sig_handler_fatal);
SIGNAL(SIGALRM, sig_handler_fatal);
SIGNAL(SIGFPE, sig_handler_fatal);
SIGNAL(SIGILL, sig_handler_fatal);
SIGNAL(SIGPIPE, sig_handler_fatal);
SIGNAL(SIGQUIT, sig_handler_fatal);
SIGNAL(SIGSEGV, sig_handler_fatal);
signal(SIGPIPE, SIG_IGN);
}
void mem_err(void)
{
char *prt = NULL;
printf("%s()\n", __func__);
*prt = '1';
}
int main(int argc, char **argv)
{
signals_setup();
int i = 0;
for (; ;) {
i ++;
if (i > 10) {
mem_err();
}
// printf("i: %d\n", i);
sleep(2);
}
return 0;
}
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);
callback: ./sig_setup() [0x804867b]: 0804865c <dbg_backtrace>: 804865c: 55 push %ebp 804865d: 89 e5 mov %esp,%ebp 804865f: 81 ec b8 01 00 00 sub $0x1b8,%esp 8048665: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) 804866c: 00 804866d: 8d 85 5c fe ff ff lea -0x1a4(%ebp),%eax 8048673: 89 04 24 mov %eax,(%esp) 8048676: e8 e5 fe ff ff call 8048560 <backtrace@plt> 804867b: 89 45 f0 mov %eax,-0x10(%ebp) callback: ./sig_setup() [0x8048791] 08048773 <sig_handler_fatal>: 8048773: 55 push %ebp 8048774: 89 e5 mov %esp,%ebp 8048776: 83 ec 18 sub $0x18,%esp 8048779: 8b 45 08 mov 0x8(%ebp),%eax 804877c: 89 44 24 04 mov %eax,0x4(%esp) 8048780: c7 04 24 15 8c 04 08 movl $0x8048c15,(%esp) 8048787: e8 14 fd ff ff call 80484a0 <printf@plt> 804878c: e8 cb fe ff ff call 804865c <dbg_backtrace> 8048791: c7 04 24 7f 00 00 00 movl $0x7f,(%esp) callback: ./sig_setup() [0x8048ae7] 08048ac3 <mem_err>: 8048ac3: 55 push %ebp 8048ac4: 89 e5 mov %esp,%ebp 8048ac6: 83 ec 28 sub $0x28,%esp 8048ac9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) 8048ad0: c7 44 24 04 5b 8c 04 movl $0x8048c5b,0x4(%esp) 8048ad7: 08 8048ad8: c7 04 24 4e 8c 04 08 movl $0x8048c4e,(%esp) 8048adf: e8 bc f9 ff ff call 80484a0 <printf@plt> 8048ae4: 8b 45 f4 mov -0xc(%ebp),%eax 8048ae7: c6 00 31 movb $0x31,(%eax)
标签:linux内核 linux c语言 debug callback
原文地址:http://blog.csdn.net/u013686019/article/details/42128771