예제 #1
0
// If configured to do so, dump memory around *all* registers
// for the crashing thread.
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
  struct pt_regs regs;
  if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
    return;
  }

  if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
    static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";

    for (int reg = 0; reg < 14; reg++) {
      // this may not be a valid way to access, but it'll do for now
      uintptr_t addr = regs.uregs[reg];

      // Don't bother if it looks like a small int or ~= null, or if
      // it's in the kernel area.
      if (addr < 4096 || addr >= 0xc0000000) {
        continue;
      }

      _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
      dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
    }
  }

  // explicitly allow upload of code dump logging
  _LOG(log, scope_flags, "\ncode around pc:\n");
  dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc), scope_flags);

  if (regs.ARM_pc != regs.ARM_lr) {
    _LOG(log, scope_flags, "\ncode around lr:\n");
    dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr), scope_flags);
  }
}
예제 #2
0
void _LOG(log_t* log, int scopeFlags, const char* fmt, ...) {
  char buf[512];
  bool want_tfd_write;
  bool want_log_write;
  bool want_amfd_write;
  int len = 0;

  va_list ap;
  va_start(ap, fmt);

  // where is the information going to go?
  want_tfd_write = log && log->tfd >= 0;
  want_log_write = IS_AT_FAULT(scopeFlags) && (!log || !log->quiet);
  want_amfd_write = IS_AT_FAULT(scopeFlags) && !IS_SENSITIVE(scopeFlags) && log && log->amfd >= 0;

  // if we're going to need the literal string, generate it once here
  if (want_tfd_write || want_amfd_write) {
    vsnprintf(buf, sizeof(buf), fmt, ap);
    len = strlen(buf);
  }

  if (want_tfd_write) {
    write(log->tfd, buf, len);
  }

  if (want_log_write) {
    // whatever goes to logcat also goes to the Activity Manager
    __android_log_vprint(ANDROID_LOG_INFO, "DEBUG", fmt, ap);
    if (want_amfd_write && len > 0) {
      int written = write_to_am(log->amfd, buf, len);
      if (written <= 0) {
        // timeout or other failure on write; stop informing the activity manager
        log->amfd = -1;
      }
    }
  }
  va_end(ap);
}
예제 #3
0
// If configured to do so, dump memory around *all* registers
// for the crashing thread.
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
  pt_regs_mips_t r;
  if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
    return;
  }

  if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
    static const char REG_NAMES[] = "$0atv0v1a0a1a2a3t0t1t2t3t4t5t6t7s0s1s2s3s4s5s6s7t8t9k0k1gpsps8ra";

    for (int reg = 0; reg < 32; reg++) {
      // skip uninteresting registers
      if (reg == 0 // $0
          || reg == 26 // $k0
          || reg == 27 // $k1
          || reg == 31 // $ra (done below)
         )
        continue;

      uintptr_t addr = R(r.regs[reg]);

      // Don't bother if it looks like a small int or ~= null, or if
      // it's in the kernel area.
      if (addr < 4096 || addr >= 0x80000000) {
        continue;
      }

      _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
      dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
    }
  }

  unsigned int pc = R(r.cp0_epc);
  unsigned int ra = R(r.regs[31]);

  _LOG(log, scope_flags, "\ncode around pc:\n");
  dump_memory(log, tid, (uintptr_t)pc, scope_flags);

  if (pc != ra) {
    _LOG(log, scope_flags, "\ncode around ra:\n");
    dump_memory(log, tid, (uintptr_t)ra, scope_flags);
  }
}