📄 hangdler.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <setjmp.h>
#include <string.h>
typedef void Sigfunc (int); /* for signal handlers */
Sigfunc *signal (int signo, Sigfunc * func);
static Sigfunc *Signal (int signo, Sigfunc * func);
static char *get_stack_bottom (void);
static void segfault (int signo);
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump = 0;
static Sigfunc *seg_handler;
static Sigfunc *bus_handler; /* for xxxBSD */
Sigfunc *
signal (int signo, Sigfunc * func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
if (sigaction (signo, &act, &oact) < 0)
{
return (SIG_ERR);
}
return (oact.sa_handler);
} /* end of signal */
static Sigfunc *
Signal (int signo, Sigfunc * func) /* for our signal() funct
ion */
{
Sigfunc *sigfunc;
if ((sigfunc = signal (signo, func)) == SIG_ERR)
{
exit (EXIT_FAILURE);
}
return (sigfunc);
} /* end of Signal */
static char *
get_stack_bottom (void)
{
volatile char *c; /* for autovar, must be volatile */
seg_handler = Signal (SIGSEGV, segfault);
bus_handler = Signal (SIGBUS, segfault);
c = (char *) &c;
if (sigsetjmp (jmpbuf, 1) != 0)
{
Signal (SIGSEGV, seg_handler);
Signal (SIGBUS, bus_handler);
printf("demo SIGSEGV: %p\n", (char *)c);
return ((char *) c);
}
canjump = 1; /* now sigsetjump() is OK */
while (1)
{
*c = *c;
c++;
}
return (NULL);
} /* end of get_stack_bottom */
static void
segfault (int signo)
{
if (canjump == 0)
{
return; /* unexpected signal, ignore */
}
canjump = 0;
siglongjmp (jmpbuf, signo); /* jump back to main, don't return */
} /* end of segfault */
/**********************************************************************************/
// ligang's method
static void get_start()
{
char filename[100];
char content[1024];
char stack_bottom[64];
FILE *fp;
char *pcontent, *ptmp;
int i;
unsigned long _ckpt_stack_bottom;
// get the address of stack
// add by lg
sprintf(filename,"/proc/%d/stat", getpid());
fp=fopen(filename,"r");
if (fp==NULL){
perror("in fopen() of get_start()");
exit(-1);
}
fread(content, 1024, 1, fp);
//the 28th element in the file stat is the address of stack
pcontent = content;
for (i=1; i<28; i++) {
pcontent = strstr(pcontent, " ");
pcontent = pcontent + 1;
}
ptmp = strstr(pcontent, " ");
strncpy(stack_bottom, pcontent, ptmp - pcontent);
stack_bottom[ptmp - pcontent] = '\0';
sscanf(stack_bottom, "%lu", &_ckpt_stack_bottom);
fclose(fp);
printf("/proc/<pid>/stat: %p\n", _ckpt_stack_bottom);
}
/********************************************************************/
// read from /proc/pid/maps
static void getStackFromMaps()
{
char filename[100];
char line[256];
char *tmpline;
FILE *fp;
char *start, *end;
sprintf(filename,"/proc/%d/maps", getpid());
fp = fopen(filename, "r");
if (fp==NULL){
perror("in fopen() of getStackFromMaps");
exit(-1);
}
/* gets the last line */
do{
tmpline = fgets(line, 256, fp);
} while(tmpline != 0);
fclose(fp);
start = strstr(line, "-") + 1;
end = strstr(line, " ");
*end = 0;
printf("/proc/<pid>/maps: 0x%s\n", start);
}
/*******************************************************************************/
// configure.c
char *ptr;
void
pgfault_handler(sig)
long sig;
{
fprintf(stderr, "configre SIGSEGV: %p\n", ptr);
exit(0);
}
void getBottomStack()
{
int stack_dummy;
signal(SIGSEGV, (void(*)(int))pgfault_handler);
ptr = (char *)&stack_dummy;
/* program calls exit(0) from signal handler */
while (1) {
*ptr = 0;
ptr += 1;
}
}
/*******************************************************************************/
int main (int argc, char *argv[])
{
printf("Current Stack Bottom:\n");
//ligang
get_start();
//demo another
get_stack_bottom();
//read from maps
getStackFromMaps();
//configure another
getBottomStack();
return (EXIT_SUCCESS);
} /* end of main */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -