Exemplo n.º 1
0
void
x86_backtrace(struct pt_regs * const regs, unsigned int depth)
{
	struct frame_head *head;

#ifdef CONFIG_X86_64
	head = (struct frame_head *)regs->rbp;
#else
	head = (struct frame_head *)regs->ebp;
#endif

	if (!user_mode(regs)) {
		while (depth-- && valid_kernel_stack(head, regs))
			head = dump_backtrace(head);
		return;
	}

#ifdef CONFIG_SMP
	if (!spin_trylock(&current->mm->page_table_lock))
		return;
#endif

	while (depth-- && head && pages_present(head))
		head = dump_backtrace(head);

#ifdef CONFIG_SMP
	spin_unlock(&current->mm->page_table_lock);
#endif
}
Exemplo n.º 2
0
static void
sig_segv(struct terminal *term)
{
    /* Get some attention. */
    fputs("\a", stderr);
    fflush(stderr);
    sleep(1);
    fputs("\a\n", stderr);

    /* Rant. */
    fputs(	"ELinks crashed. That shouldn't happen. Please report this incident to\n"
            "the developers. If you would like to help to debug the problem you just\n"
            "uncovered, please keep the core you just got and send the developers\n"
            "the output of 'bt' command entered inside of gdb (which you run as:\n"
            "gdb elinks core). Thanks a lot for your cooperation!\n\n", stderr);

    /* version information */
    fputs(full_static_version, stderr);
    fputs("\n\n", stderr);

    /* Backtrace. */
    dump_backtrace(stderr, 1);

    /* TODO: Perhaps offer launching of gdb? Or trying to continue w/
     * program execution? --pasky */

    /* The fastest way OUT! */
    abort();
}
Exemplo n.º 3
0
static int __die(const char *str, int err, struct pt_regs *regs)
{
	struct task_struct *tsk = current;
	static int die_counter;
	int ret;

	pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
		 str, err, ++die_counter);

	/* trap and error numbers are mostly meaningless on ARM */
	ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV);
	if (ret == NOTIFY_STOP)
		return ret;

	print_modules();
	__show_regs(regs);
	pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk),
		 end_of_stack(tsk));

	if (!user_mode(regs)) {
		dump_backtrace(regs, tsk);
		dump_instr(KERN_EMERG, regs);
	}

	return ret;
}
Exemplo n.º 4
0
static int __die(const char *str, int err, struct thread_info *thread,
		 struct pt_regs *regs)
{
	struct task_struct *tsk = thread->task;
	static int die_counter;
	int ret;

	pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
		 str, err, ++die_counter);

	/* trap and error numbers are mostly meaningless on ARM */
	ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV);
	if (ret == NOTIFY_STOP)
		return ret;

	print_modules();
	__show_regs(regs);
	pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);

	if (!user_mode(regs) || in_interrupt()) {
		dump_mem(KERN_EMERG, "Stack: ", regs->sp,
			 THREAD_SIZE + (unsigned long)task_stack_page(tsk));
		dump_backtrace(regs, tsk);
		dump_instr(KERN_EMERG, regs);
	}

	return ret;
}
Exemplo n.º 5
0
static void sig_proc(int sn)
{
	static int is_called = 0;

	switch (sn) 
	{
		case SIGINT:
		case SIGTERM:
			if (++is_called > 3)
				do_final(EXIT_SUCCESS);
			runflag = 0;
			break;
		case SIGSEGV:
		case SIGFPE:
			dump_backtrace();
			do_abort();
			// Pass the signal to the system's default handler
			compat_signal(sn, SIG_DFL);
			raise(sn);
			break;
#ifndef _WIN32
		case SIGXFSZ:
			// ignore and allow it to set errno to EFBIG
			ShowWarning ("Max file size reached!\n");
			//run_flag = 0;	// should we quit?
			break;
		case SIGPIPE:
			//ShowInfo ("Broken pipe found... closing socket\n");	// set to eof in socket.c
			break;	// does nothing here
#endif
	}
}
Exemplo n.º 6
0
/* Throws an ad-hoc (untyped) exception. */
MVM_NO_RETURN
void MVM_exception_throw_adhoc_va(MVMThreadContext *tc, const char *messageFormat, va_list args) {
    /* Needs plugging in to the exceptions mechanism. */
    vfprintf(stderr, messageFormat, args);
    fwrite("\n", 1, 1, stderr);
    dump_backtrace(tc);
    exit(1);
}
Exemplo n.º 7
0
static bool perform_dump(const debugger_request_t& request, int fd, int tombstone_fd,
                         BacktraceMap* backtrace_map, const std::set<pid_t>& siblings,
                         int* crash_signal) {
  if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
    ALOGE("debuggerd: failed to respond to client: %s\n", strerror(errno));
    return false;
  }

  int total_sleep_time_usec = 0;
  while (true) {
    int signal = wait_for_signal(request.tid, &total_sleep_time_usec);
    switch (signal) {
      case -1:
        ALOGE("debuggerd: timed out waiting for signal");
        return false;

      case SIGSTOP:
        if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
          ALOGV("debuggerd: stopped -- dumping to tombstone");
          engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal,
                            request.original_si_code, request.abort_msg_address);
        } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
          ALOGV("debuggerd: stopped -- dumping to fd");
          dump_backtrace(fd, -1, backtrace_map, request.pid, request.tid, siblings);
        } else {
          ALOGV("debuggerd: stopped -- continuing");
          if (ptrace(PTRACE_CONT, request.tid, 0, 0) != 0) {
            ALOGE("debuggerd: ptrace continue failed: %s", strerror(errno));
            return false;
          }
          continue;  // loop again
        }
        break;

      case SIGABRT:
      case SIGBUS:
      case SIGFPE:
      case SIGILL:
      case SIGSEGV:
#ifdef SIGSTKFLT
      case SIGSTKFLT:
#endif
      case SIGTRAP:
        ALOGV("stopped -- fatal signal\n");
        *crash_signal = signal;
        engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal,
                          request.original_si_code, request.abort_msg_address);
        break;

      default:
        ALOGE("debuggerd: process stopped due to unexpected signal %d\n", signal);
        break;
    }
    break;
  }

  return true;
}
Exemplo n.º 8
0
/* Panic over an unhandled exception object. */
static void panic_unhandled_ex(MVMThreadContext *tc, MVMException *ex) {
    /* If there's no message, fall back to category. */
    if (!ex->body.message)
        panic_unhandled_cat(tc, ex->body.category);

    /* Otherwise, dump message and a backtrace. */
    fprintf(stderr, "Unhandled exception: %s\n",
        MVM_string_utf8_encode_C_string(tc, ex->body.message));
    dump_backtrace(tc);
    exit(1);
}
Exemplo n.º 9
0
void sig_segv( struct terminal *term )
{
  fputc( 7, stderr );
  fflush( stderr );
  sleep( 1 );
  fwrite( "\n", 1, 2, stderr );
  fwrite( "ELinks crashed. That shouldn't happen. Please report this incident to\nthe developers. If you would like to help to debug the problem you just\nuncovered, please keep the core you just got and send the developers\nthe output of 'bt' command entered inside of gdb (which you run as:\ngdb elinks core). Thanks a lot for your cooperation!\n\n", 1, 333, stderr );
  fputs( full_static_version, stderr );
  fwrite( "\n\n", 1, 2, stderr );
  dump_backtrace( stderr, 1 );
  abort(  );
}
Exemplo n.º 10
0
int dump_stack(void)
{
	char buff[4096];

	if (dump_backtrace(buff, sizeof(buff))== NULL) {
		return -EFAULT;
	}

	pd_info("%s", buff);

	return 0;
}
Exemplo n.º 11
0
EXTERNAL void
message (int flags, const char *file, const char *function, int line,
         const char *fmt, ...)
{
  char *level = NULL;
  va_list ap;

  if (flags & MESSAGE_INFO)
    {
      level = "Info";
    }
  else if (flags & MESSAGE_WARNING)
    {
      level = "Warning";
    }
  else if (flags & MESSAGE_ERROR)
    {
      level = "Error";
    }
  else if (flags & MESSAGE_FATAL)
    {
      level = "Fatal";
    }

  fprintf (stderr, "%s:%s:%s:%d:", level, file, function, line);

  va_start (ap, fmt);
  vfprintf (stderr, fmt, ap);
  va_end (ap);

  fprintf (stderr, "\n");
  fflush (stderr);

  if (flags & (MESSAGE_INFO | MESSAGE_WARNING | MESSAGE_ERROR | MESSAGE_FATAL))
    {
      syslog (LOG_ERR, "%s:%s:%s:%d:", level, file, function, line);

      va_start (ap, fmt);
      vsyslog (LOG_ERR, fmt, ap);
      va_end (ap);
    }

  if (flags & MESSAGE_FATAL)
    {
      dump_backtrace ();
      abort ();
    }
}
Exemplo n.º 12
0
/* Throws an ad-hoc (untyped) formatted exception with an apr error appended. */
MVM_NO_RETURN
void MVM_exception_throw_apr_error(MVMThreadContext *tc, apr_status_t code, const char *messageFormat, ...) {
    /* Needs plugging in to the exceptions mechanism. */
    char *error_string = malloc(512);
    int offset;
    va_list args;
    va_start(args, messageFormat);
    
    /* inject the supplied formatted string */
    offset = vsprintf(error_string, messageFormat, args);
    va_end(args);
    
    /* append the apr error */
    apr_strerror(code, error_string + offset, 512 - offset);
    fwrite(error_string, 1, strlen(error_string), stderr);
    fwrite("\n", 1, 1, stderr);
    free(error_string);
    
    dump_backtrace(tc);
    exit(1);
}
Exemplo n.º 13
0
static int bug_handler(struct pt_regs *regs, unsigned int esr)
{
	if (user_mode(regs))
		return DBG_HOOK_ERROR;

	switch (report_bug(regs->pc, regs)) {
	case BUG_TRAP_TYPE_BUG:
		die("Oops - BUG", regs, 0);
		break;

	case BUG_TRAP_TYPE_WARN:
		/* Ideally, report_bug() should backtrace for us... but no. */
		dump_backtrace(regs, NULL);
		break;

	default:
		/* unknown/unrecognised bug trap type */
		return DBG_HOOK_ERROR;
	}

	/* If thread survives, skip over the BUG instruction and continue: */
	regs->pc += AARCH64_INSN_SIZE;	/* skip BRK and resume */
	return DBG_HOOK_HANDLED;
}
Exemplo n.º 14
0
static void handle_request(int fd) {
  ALOGV("handle_request(%d)\n", fd);

  debugger_request_t request;
  memset(&request, 0, sizeof(request));
  int status = read_request(fd, &request);
  if (!status) {
    ALOGV("BOOM: pid=%d uid=%d gid=%d tid=%d\n",
         request.pid, request.uid, request.gid, request.tid);

    // At this point, the thread that made the request is blocked in
    // a read() call.  If the thread has crashed, then this gives us
    // time to PTRACE_ATTACH to it before it has a chance to really fault.
    //
    // The PTRACE_ATTACH sends a SIGSTOP to the target process, but it
    // won't necessarily have stopped by the time ptrace() returns.  (We
    // currently assume it does.)  We write to the file descriptor to
    // ensure that it can run as soon as we call PTRACE_CONT below.
    // See details in bionic/libc/linker/debugger.c, in function
    // debugger_signal_handler().
    if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) {
      ALOGE("ptrace attach failed: %s\n", strerror(errno));
    } else {
      bool detach_failed = false;
      bool attach_gdb = should_attach_gdb(&request);
      if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
        ALOGE("failed responding to client: %s\n", strerror(errno));
      } else {
        char* tombstone_path = NULL;

        if (request.action == DEBUGGER_ACTION_CRASH) {
          close(fd);
          fd = -1;
        }

        int total_sleep_time_usec = 0;
        for (;;) {
          int signal = wait_for_signal(request.tid, &total_sleep_time_usec);
          if (signal < 0) {
            break;
          }

          switch (signal) {
            case SIGSTOP:
              if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
                ALOGV("stopped -- dumping to tombstone\n");
                tombstone_path = engrave_tombstone(request.pid, request.tid,
                                                   signal, request.original_si_code,
                                                   request.abort_msg_address, true,
                                                   &detach_failed, &total_sleep_time_usec);
              } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
                ALOGV("stopped -- dumping to fd\n");
                dump_backtrace(fd, -1, request.pid, request.tid, &detach_failed,
                               &total_sleep_time_usec);
              } else {
                ALOGV("stopped -- continuing\n");
                status = ptrace(PTRACE_CONT, request.tid, 0, 0);
                if (status) {
                  ALOGE("ptrace continue failed: %s\n", strerror(errno));
                }
                continue; // loop again
              }
              break;

            case SIGABRT:
            case SIGBUS:
            case SIGFPE:
            case SIGILL:
            case SIGPIPE:
            case SIGSEGV:
#ifdef SIGSTKFLT
            case SIGSTKFLT:
#endif
            case SIGTRAP:
              ALOGV("stopped -- fatal signal\n");
              // Send a SIGSTOP to the process to make all of
              // the non-signaled threads stop moving.  Without
              // this we get a lot of "ptrace detach failed:
              // No such process".
              kill(request.pid, SIGSTOP);
              // don't dump sibling threads when attaching to GDB because it
              // makes the process less reliable, apparently...
              tombstone_path = engrave_tombstone(request.pid, request.tid,
                                                 signal, request.original_si_code,
                                                 request.abort_msg_address, !attach_gdb,
                                                 &detach_failed, &total_sleep_time_usec);
              break;

            default:
              ALOGE("process stopped due to unexpected signal %d\n", signal);
              break;
          }
          break;
        }

        if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
          if (tombstone_path) {
            write(fd, tombstone_path, strlen(tombstone_path));
          }
          close(fd);
          fd = -1;
        }
        free(tombstone_path);
      }

      ALOGV("detaching\n");
      if (attach_gdb) {
        // stop the process so we can debug
        kill(request.pid, SIGSTOP);

        // detach so we can attach gdbserver
        if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
          ALOGE("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
          detach_failed = true;
        }

        // if debug.db.uid is set, its value indicates if we should wait
        // for user action for the crashing process.
        // in this case, we log a message and turn the debug LED on
        // waiting for a gdb connection (for instance)
        wait_for_user_action(request);
      } else {
        // just detach
        if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
          ALOGE("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
          detach_failed = true;
        }
      }

      // resume stopped process (so it can crash in peace).
      kill(request.pid, SIGCONT);

      // If we didn't successfully detach, we're still the parent, and the
      // actual parent won't receive a death notification via wait(2).  At this point
      // there's not much we can do about that.
      if (detach_failed) {
        ALOGE("debuggerd committing suicide to free the zombie!\n");
        kill(getpid(), SIGKILL);
      }
    }

  }
  if (fd >= 0) {
    close(fd);
  }
}
Exemplo n.º 15
0
void show_stack(struct task_struct *tsk, unsigned long *sp)
{
	dump_backtrace(NULL, tsk);
	barrier();
}
Exemplo n.º 16
0
void assert_with_backtrace(const char *msg, const char *file, int line)
{
    printf("Assertion failed!\n");
    dump_backtrace();
    __assert(msg, file, line);
}
Exemplo n.º 17
0
/* Panic over an unhandled exception throw by category. */
static void panic_unhandled_cat(MVMThreadContext *tc, MVMuint32 cat) {
    fprintf(stderr, "No exception handler located for %s\n", cat_name(tc, cat));
    dump_backtrace(tc);
    exit(1);
}
Exemplo n.º 18
0
void show_regs(struct pt_regs * regs)
{
	__show_regs(regs);
	dump_backtrace(regs, NULL);
}
Exemplo n.º 19
0
Arquivo: traps.c Projeto: 4atty/linux
void dump_stack(void)
{
	dump_backtrace(NULL, NULL);
}