Esempio n. 1
0
void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
  greg_t  *pc;
  greg_t  *npc;
  greg_t  *sp;
  greg_t  *fp;
#ifdef WAD_LINUX
  greg_t  *esi;
  greg_t  *edi;
  greg_t  *ebx;
#endif

  unsigned long   addr;
  ucontext_t      *context;
  unsigned long   p_sp;        /* process stack pointer   */
  unsigned long   p_pc;        /* Process program counter */
  unsigned long   p_fp;        /* Process frame pointer   */
  int      nlevels = 0;
  int      found = 0;
  void     _returnsignal();
  WadFrame  *frame, *origframe;
  char      *framedata;
  char      *retname = 0;
  unsigned long current_brk;

  /* Reset all of the signals while running WAD */
  wad_signal_clear();

  wad_nlr_func = 0;

  context = (ucontext_t *) vcontext;

  wad_printf("WAD: Collecting debugging information...\n");

  /* Read the segments */
  if (wad_segment_read() < 0) {
    wad_printf("WAD: Unable to read segment map\n");
    return;
  }
 
  if (wad_debug_mode & DEBUG_SIGNAL) {
    wad_printf("WAD: siginfo = %x, context = %x\n", si, vcontext);
  }
  
  current_brk = (long) sbrk(0);

  /* Get some information about the current context */

#ifdef WAD_SOLARIS
  pc = &((context->uc_mcontext).gregs[REG_PC]);
  npc = &((context->uc_mcontext).gregs[REG_nPC]);
  sp = &((context->uc_mcontext).gregs[REG_SP]);
#endif

#ifdef WAD_LINUX
  sp = &((context->uc_mcontext).gregs[ESP]);        /* Top of stack */
  fp = &((context->uc_mcontext).gregs[EBP]);        /* Stack base - frame pointer */
  pc = &((context->uc_mcontext).gregs[EIP]);        /* Current instruction */
  esi = &((context->uc_mcontext).gregs[ESI]);       
  edi = &((context->uc_mcontext).gregs[EDI]);       
  ebx = &((context->uc_mcontext).gregs[EBX]);       
  
  wad_saved_esi = (unsigned long) (*esi);
  wad_saved_edi = (unsigned long) (*edi);
  wad_saved_ebx = (unsigned long) (*ebx);

  /*  printf("esi = %x, edi = %x, ebx = %x\n", wad_saved_esi, wad_saved_edi, wad_saved_ebx); */

  /*   printf("&sp = %x, &pc = %x\n", sp, pc); */
#endif
  
  /* Get some information out of the signal handler stack */
  addr = (unsigned long) si->si_addr;

  /* See if this might be a stack overflow */

  p_pc = (unsigned long) (*pc);
  p_sp = (unsigned long) (*sp);
#ifdef WAD_LINUX
  p_fp = (unsigned long) (*fp);
#endif
#ifdef WAD_SOLARIS
  p_fp = (unsigned long) *(((long *) p_sp) + 14);
#endif
  
  if (wad_debug_mode & DEBUG_SIGNAL) {
    wad_printf("fault at address %x, pc = %x, sp = %x, fp = %x\n", addr, p_pc, p_sp, p_fp);
  }
  frame = wad_stack_trace(p_pc, p_sp, p_fp);

  if (!frame) {
    /* We're really hosed.  Not possible to generate a stack trace */
    wad_printf("WAD: Unable to generate stack trace.\n");
    wad_printf("WAD: Maybe the call stack has been corrupted by buffer overflow.\n");
    wad_signal_clear();
    return;
  }

  {
    WadFrame *f = frame;
    while (f) {
      wad_find_object(f);
      wad_find_symbol(f);
      f = f->next;
    }
    f = frame;
    while (f) {
      wad_find_debug(f);
      wad_build_vars(f);
      f = f->next;
    }
  }
  wad_heap_overflow = 0;
  if (sig == SIGSEGV) {
    if (addr >= current_brk) wad_heap_overflow = 1;
  }

  wad_stack_debug(frame);

  /* Generate debugging strings */
  wad_debug_make_strings(frame);
  
  wad_stab_debug();

  /* Walk the exception frames and try to find a return point */
  origframe = frame;
  while (frame) {
    WadReturnFunc *wr = wad_check_return(frame->sym_name);
    if (wr) {
      found = 1;
      wad_nlr_value = wr->value;
      retname = wr->name;
    }
    if (found) {
      frame->last = 1;   /* Cut off top of the stack trace */
      break;
    }
    frame = frame->next;
    nlevels++;
  }
  

  if (found) {
    wad_nlr_levels = nlevels - 1;
#ifdef WAD_LINUX
    wad_restore_i386_registers(origframe, wad_nlr_levels);
#endif
  } else {
    wad_nlr_levels = -1;
  }

  wad_string_debug();
  wad_memory_debug();

  /* Before we do anything with callbacks, we are going
     to attempt to dump a wad-core */
  
  {
    int fd;
    static int already = 0;
    fd = open("wadtrace",O_WRONLY | O_CREAT | (already*O_APPEND) | ((already==0)*O_TRUNC),0666);
    if (fd > 0) {
      wad_dump_trace(fd,sig,origframe,retname);
      close(fd);
      already=1;
    }
  }

  if (sig_callback) {
    (*sig_callback)(sig,origframe,retname);
  } else {
    /* No signal handler defined.  Go invoke the default */

    wad_default_callback(sig, origframe,retname);
  }

  if (wad_debug_mode & DEBUG_HOLD) while(1);

  /* If we found a function to which we should return, we jump to
     an alternative piece of code that unwinds the stack and 
     initiates a non-local return. */

  if (wad_nlr_levels >= 0) {
    *(pc) = (greg_t) _returnsignal;
#ifdef WAD_SOLARIS
    *(npc) = *(pc) + 4;
#endif
    if (!(wad_debug_mode & DEBUG_ONESHOT)) {
      wad_signal_init();
    }
    return;
  }
  exit(1);
}
Esempio n. 2
0
/* Handler function */	
static void handler(int signo, WadFrame *frame, char *ret) {
  static char message[65536];
  static char temp[1024];
  int  len = 0;
  PyObject *type;
  char *name;
  WadFrame *f;
  WadFrame *fline = 0;
  char     *srcstr = 0;

  /*  printf("python handler.\n"); */
  if (!ret) {
    wad_default_callback(signo, frame, ret);
    return;
  }

  strcpy(message,"[ C stack trace ]\n\n");
  switch(signo) {
  case SIGSEGV:
    type = segfault_exc;
    break;
  case SIGBUS:
    type = buserror_exc;
    break;
  case SIGABRT:
    type = abort_exc;
    break;
  case SIGFPE:
    type = PyExc_FloatingPointError;
    break;
  case SIGILL:
    type = illegal_exc;
    break;
  default:
    type = PyExc_RuntimeError;
    break;
  }

#ifdef OLD
  f = frame;
  /* Find the last exception frame */
  while (!f->last) {
    f= f->next;
  }
  /* Now work backwards */
  f = f->prev;
  while (f) {
    strcat(message, f->debug_str);
    if (f->debug_srcstr) srcstr = f->debug_srcstr;
    f = f->prev;
  }
  if (srcstr) {
    strcat(message,"\n");
    strcat(message, srcstr);
    strcat(message,"\n");
  }
#endif

  if (wad_heap_overflow) {
    write(2, "WAD: Heap overflow detected.\n", 30);
    wad_default_callback(signo, frame, ret);
  }

  /* Note: if the heap is blown, there is a very good chance that this
  function will not succeed and we'll dump core.  However, the check
  above should dump a stack trace to stderr just in case we don't make it
  back. */

#ifdef OLD
  PyErr_SetString(type, message);
#endif
  PyErr_SetObject(type, new_wadobject(frame,0));

}
Esempio n. 3
0
/* Handler function */	
static void handler(int signo, WadFrame *frame, char *ret) {
  static char message[65536];
  static char temp[1024];
  int  len = 0;
  char *name;
  WadFrame *f;
  WadFrame *fline = 0;
  char *srcstr= 0;
  Tcl_Interp *interp;
  int err;
  char  *type;

  if (!ret) {
    wad_default_callback(signo, frame, ret);
    return;
  }

  strcpy(message,"[ C stack trace ]\n\n");
  switch(signo) {
  case SIGSEGV:
    type = (char*)"Segmentation fault.";
    break;
  case SIGBUS:
    type = (char*)"Bus error.";
    break;
  case SIGABRT:
    type = (char*)"Abort.";
    break;
  case SIGFPE:
    type = (char*)"Floating point exception.";
    break;
  default:
    type = (char*)"Unknown.";
    break;
  }

  f = frame;
  /* Find the last exception frame */
  while (!f->last) {
    f= f->next;
  }
  /* Now work backwards */
  f = f->prev;
  while (f) {
    strcat(message, f->debug_str);
    if (f->debug_srcstr) srcstr = f->debug_srcstr;
    f = f->prev;
  }
  if (srcstr) {
    strcat(message,"\n");
    strcat(message, srcstr);
    strcat(message,"\n");
  }

  if (wad_heap_overflow) {
    write(2, "WAD: Heap overflow detected.\n", 30);
    wad_default_callback(signo, frame, ret);
  }

  /* Note: if the heap is blown, there is a very good chance that this
  function will not succeed and we'll dump core.  However, the check
  above should dump a stack trace to stderr just in case we don't make it
  back. */

  /* Try to get the Tcl interpreter through magic */
  if (ret) {
    interp = (Tcl_Interp *) wad_steal_outarg(frame,ret,1,&err);
    if (err == 0) {
      Tcl_SetResult(interp,type,TCL_STATIC);
      Tcl_AddErrorInfo(interp,message);
    }
  }
}