Пример #1
0
 bool crash_handler::need_write_dump()
 {
     if (!is_crash_handle_enabled())
         return false;
     if (get_dump_type() == -1)
         return false;
     return true;
 }
Пример #2
0
        // This method creates minidump of the process
        void crash_handler::create_mini_dump(EXCEPTION_POINTERS* pExcPtrs)
        {   
            MINIDUMP_EXCEPTION_INFORMATION mei;
            MINIDUMP_CALLBACK_INFORMATION mci;

            // Load dbghelp.dll
            HMODULE hDbgHelp = LoadLibrary(_T("dbghelp.dll"));
            if(hDbgHelp == NULL)
            {
                // Error - couldn't load dbghelp.dll
                return;
            }

            // create folder if not existed
            if (!CreateDirectory((get_report_path() + std::wstring(L"\\")).c_str(), NULL) &&
                ERROR_ALREADY_EXISTS != GetLastError())
            {
                return;
            }

            create_log_file_for_hockey_app(pExcPtrs);

            // Create the minidump file
            HANDLE handleFile (CreateFile(
                get_report_mini_dump_path().c_str(),
                GENERIC_WRITE,
                0,
                NULL,
                CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                NULL));

            // https://msdn.microsoft.com/ru-ru/library/windows/desktop/5fc6ft2t(v=vs.80).aspx
            if(handleFile==INVALID_HANDLE_VALUE)
            {
                return;
            }

            CHandle hFile(handleFile);

            // Write minidump to the file
            mei.ThreadId = GetCurrentThreadId();
            mei.ExceptionPointers = pExcPtrs;
            mei.ClientPointers = FALSE;
            mci.CallbackRoutine = NULL;
            mci.CallbackParam = NULL;

            typedef BOOL (WINAPI *LPMINIDUMPWRITEDUMP)(
                HANDLE hProcess, 
                DWORD ProcessId, 
                HANDLE hFile, 
                MINIDUMP_TYPE DumpType, 
                CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 
                CONST PMINIDUMP_USER_STREAM_INFORMATION UserEncoderParam, 
                CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);

            LPMINIDUMPWRITEDUMP pfnMiniDumpWriteDump = 
                (LPMINIDUMPWRITEDUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
            if(!pfnMiniDumpWriteDump)
            {    
                // Bad MiniDumpWriteDump function
                return;
            }

            HANDLE hProcess = GetCurrentProcess();
            DWORD dwProcessId = GetCurrentProcessId();
            auto dump_type = (_MINIDUMP_TYPE)get_dump_type();
            if (dump_type == -1)
            {
                assert(!"dump_type must be positive");
                dump_type = MiniDumpNormal;
            }

            BOOL bWriteDump = pfnMiniDumpWriteDump(
                hProcess,
                dwProcessId,
                hFile,
                dump_type,
                &mei,
                NULL,
                &mci);

            if(!bWriteDump)
            {    
                // Error writing dump.
                return;
            }

            // Unload dbghelp.dll
            FreeLibrary(hDbgHelp);
        }
Пример #3
0
static int debuggerd_dispatch_pseudothread(void* arg) {
  debugger_thread_info* thread_info = static_cast<debugger_thread_info*>(arg);

  for (int i = 0; i < 1024; ++i) {
    close(i);
  }

  int devnull = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));

  // devnull will be 0.
  TEMP_FAILURE_RETRY(dup2(devnull, STDOUT_FILENO));
  TEMP_FAILURE_RETRY(dup2(devnull, STDERR_FILENO));

  int pipefds[2];
  if (pipe(pipefds) != 0) {
    fatal_errno("failed to create pipe");
  }

  // Don't use fork(2) to avoid calling pthread_atfork handlers.
  int forkpid = clone(nullptr, nullptr, 0, nullptr);
  if (forkpid == -1) {
    async_safe_format_log(ANDROID_LOG_FATAL, "libc",
                          "failed to fork in debuggerd signal handler: %s", strerror(errno));
  } else if (forkpid == 0) {
    TEMP_FAILURE_RETRY(dup2(pipefds[1], STDOUT_FILENO));
    close(pipefds[0]);
    close(pipefds[1]);

    raise_caps();

    char main_tid[10];
    char pseudothread_tid[10];
    char debuggerd_dump_type[10];
    async_safe_format_buffer(main_tid, sizeof(main_tid), "%d", thread_info->crashing_tid);
    async_safe_format_buffer(pseudothread_tid, sizeof(pseudothread_tid), "%d",
                             thread_info->pseudothread_tid);
    async_safe_format_buffer(debuggerd_dump_type, sizeof(debuggerd_dump_type), "%d",
                             get_dump_type(thread_info));

    execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, main_tid, pseudothread_tid, debuggerd_dump_type,
          nullptr);

    fatal_errno("exec failed");
  } else {
    close(pipefds[1]);
    char buf[4];
    ssize_t rc = TEMP_FAILURE_RETRY(read(pipefds[0], &buf, sizeof(buf)));
    if (rc == -1) {
      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "read of IPC pipe failed: %s",
                            strerror(errno));
    } else if (rc == 0) {
      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper failed to exec");
    } else if (rc != 1) {
      async_safe_format_log(ANDROID_LOG_FATAL, "libc",
                            "read of IPC pipe returned unexpected value: %zd", rc);
    } else {
      if (buf[0] != '\1') {
        async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper reported failure");
      } else {
        thread_info->crash_dump_started = true;
      }
    }
    close(pipefds[0]);

    // Don't leave a zombie child.
    int status;
    if (TEMP_FAILURE_RETRY(waitpid(forkpid, &status, 0)) == -1) {
      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
                            strerror(errno));
    } else if (WIFSTOPPED(status) || WIFSIGNALED(status)) {
      async_safe_format_log(ANDROID_LOG_FATAL, "libc", "crash_dump helper crashed or stopped");
      thread_info->crash_dump_started = false;
    }
  }

  syscall(__NR_exit, 0);
  return 0;
}