Home | History | Annotate | Download | only in crash_collector
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "crash_dispatcher"
     18 
     19 #include <vector>
     20 
     21 #include <elf.h>
     22 #include <errno.h>
     23 #include <unistd.h>
     24 
     25 #include <android-base/file.h>
     26 #include <log/logger.h>
     27 
     28 namespace {
     29 
     30 const char kCrashCollector32Path[] = "/system/bin/crash_collector32";
     31 const char kCrashCollector64Path[] = "/system/bin/crash_collector64";
     32 
     33 }  // namespace
     34 
     35 // Reads the coredump from STDIN and checks whether it's 32-bit or 64-bit,
     36 // and dispatches it to the appropriate version of crash_collector.
     37 int main(int argc, char** argv) {
     38   // Do not abort on a write error caused by a broken pipe.
     39   signal(SIGPIPE, SIG_IGN);
     40   // Read the ELF header until EI_CLASS.
     41   char buf_head[EI_CLASS + 1];
     42   if (!android::base::ReadFully(STDIN_FILENO, buf_head, sizeof(buf_head))) {
     43     ALOGE("Failed to read. errno = %d", errno);
     44     return 1;
     45   }
     46   // Set up pipe to feed coredump to crash_collector.
     47   int pipe_fds[2];
     48   if (pipe(pipe_fds) == -1) {
     49     ALOGE("Failed to pipe. errno = %d", errno);
     50     return 1;
     51   }
     52   // Prepare crash_collector arguments.
     53   const char* crash_collector_path = buf_head[EI_CLASS] == ELFCLASS64 ?
     54       kCrashCollector64Path : kCrashCollector32Path;
     55   std::vector<const char*> args(argc + 1);
     56   args[0] = crash_collector_path;
     57   std::copy(argv + 1, argv + argc, args.begin() + 1);
     58   args.back() = nullptr;
     59   // Exec crash_collector.
     60   const pid_t pid = fork();
     61   if (pid == -1) {
     62     ALOGE("Failed to fork. errno = %d", errno);
     63     return 1;
     64   }
     65   if (pid == 0) {
     66     if (close(pipe_fds[1]) != 0 && errno != EINTR) {
     67       ALOGE("Failed to close the pipe's write end. errno = %d", errno);
     68       _exit(1);
     69     }
     70     if (TEMP_FAILURE_RETRY(dup2(pipe_fds[0], STDIN_FILENO)) != 0) {
     71       ALOGE("Failed to dup the pipe's read end. errno = %d", errno);
     72       _exit(1);
     73     }
     74     execve(args[0], const_cast<char**>(&args[0]), environ);
     75     ALOGE("Failed to execute crash_collector. errno = %d", errno);
     76     _exit(1);
     77   }
     78   // Send buf_head to crash_collector.
     79   if (close(pipe_fds[0]) != 0 && errno != EINTR) {
     80     ALOGE("Failed to close the pipe's read end.");
     81     return 1;
     82   }
     83   if (!android::base::WriteFully(pipe_fds[1], buf_head, sizeof(buf_head))) {
     84     return 1;
     85   }
     86   // Send the rest of coredump to crash_collector.
     87   const size_t kBufSize = 32768;
     88   char buf[kBufSize];
     89   while (true) {
     90     int rv = TEMP_FAILURE_RETRY(read(STDIN_FILENO, buf, kBufSize));
     91     if (rv == -1) {
     92       ALOGE("Failed to read. errno = %d", errno);
     93       return 1;
     94     }
     95     if (rv == 0)
     96       break;
     97     if (!android::base::WriteFully(pipe_fds[1], buf, rv)) {
     98       return 1;
     99     }
    100   }
    101   return 0;
    102 }
    103