OSDN Git Service

DO NOT MERGE. Added a is_zipping() function.
authorFelipe Leme <felipeal@google.com>
Fri, 21 Oct 2016 23:53:47 +0000 (23:53 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Fri, 21 Oct 2016 23:53:47 +0000 (23:53 +0000)
am: 03974984bf

Change-Id: Ib14224bf42315b3b1633662fac1f88610a824296

1  2 
cmds/dumpstate/dumpstate.cpp

@@@ -183,139 -182,9 +183,139 @@@ static void dump_dev_files(const char *
      closedir(d);
  }
  
 +// return pid of a userspace process. If not found or error, return 0.
 +static unsigned int pid_of_process(const char* ps_name) {
 +    DIR *proc_dir;
 +    struct dirent *ps;
 +    unsigned int pid;
 +    std::string cmdline;
 +
 +    if (!(proc_dir = opendir("/proc"))) {
 +        MYLOGE("Can't open /proc\n");
 +        return 0;
 +    }
 +
 +    while ((ps = readdir(proc_dir))) {
 +        if (!(pid = atoi(ps->d_name))) {
 +            continue;
 +        }
 +        android::base::ReadFileToString("/proc/"
 +                + std::string(ps->d_name) + "/cmdline", &cmdline);
 +        if (cmdline.find(ps_name) == std::string::npos) {
 +            continue;
 +        } else {
 +            closedir(proc_dir);
 +            return pid;
 +        }
 +    }
 +    closedir(proc_dir);
 +    return 0;
 +}
 +
 +// dump anrd's trace and add to the zip file.
 +// 1. check if anrd is running on this device.
 +// 2. send a SIGUSR1 to its pid which will dump anrd's trace.
 +// 3. wait until the trace generation completes and add to the zip file.
 +static bool dump_anrd_trace() {
 +    unsigned int pid;
 +    char buf[50], path[PATH_MAX];
 +    struct dirent *trace;
 +    struct stat st;
 +    DIR *trace_dir;
 +    int retry = 5;
 +    long max_ctime = 0, old_mtime;
 +    long long cur_size = 0;
 +    const char *trace_path = "/data/misc/anrd/";
 +
 +    if (!zip_writer) {
 +        MYLOGE("Not dumping anrd trace because zip_writer is not set\n");
 +        return false;
 +    }
 +
 +    // find anrd's pid if it is running.
 +    pid = pid_of_process("/system/xbin/anrd");
 +
 +    if (pid > 0) {
 +        if (stat(trace_path, &st) == 0) {
 +            old_mtime = st.st_mtime;
 +        } else {
 +            MYLOGE("Failed to find: %s\n", trace_path);
 +            return false;
 +        }
 +
 +        // send SIGUSR1 to the anrd to generate a trace.
 +        sprintf(buf, "%u", pid);
 +        if (run_command("ANRD_DUMP", 1, "kill", "-SIGUSR1", buf, NULL)) {
 +            MYLOGE("anrd signal timed out. Please manually collect trace\n");
 +            return false;
 +        }
 +
 +        while (retry-- > 0 && old_mtime == st.st_mtime) {
 +            sleep(1);
 +            stat(trace_path, &st);
 +        }
 +
 +        if (retry < 0 && old_mtime == st.st_mtime) {
 +            MYLOGE("Failed to stat %s or trace creation timeout\n", trace_path);
 +            return false;
 +        }
 +
 +        // identify the trace file by its creation time.
 +        if (!(trace_dir = opendir(trace_path))) {
 +            MYLOGE("Can't open trace file under %s\n", trace_path);
 +        }
 +        while ((trace = readdir(trace_dir))) {
 +            if (strcmp(trace->d_name, ".") == 0
 +                    || strcmp(trace->d_name, "..") == 0) {
 +                continue;
 +            }
 +            sprintf(path, "%s%s", trace_path, trace->d_name);
 +            if (stat(path, &st) == 0) {
 +                if (st.st_ctime > max_ctime) {
 +                    max_ctime = st.st_ctime;
 +                    sprintf(buf, "%s", trace->d_name);
 +                }
 +            }
 +        }
 +        closedir(trace_dir);
 +
 +        // Wait until the dump completes by checking the size of the trace.
 +        if (max_ctime > 0) {
 +            sprintf(path, "%s%s", trace_path, buf);
 +            while(true) {
 +                sleep(1);
 +                if (stat(path, &st) == 0) {
 +                    if (st.st_size == cur_size) {
 +                        break;
 +                    } else if (st.st_size > cur_size) {
 +                        cur_size = st.st_size;
 +                    } else {
 +                        return false;
 +                    }
 +                } else {
 +                    MYLOGE("Cant stat() %s anymore\n", path);
 +                    return false;
 +                }
 +            }
 +            // Add to the zip file.
 +            if (!add_zip_entry("anrd_trace.txt", path)) {
 +                MYLOGE("Unable to add anrd_trace file %s to zip file\n", path);
 +            } else {
 +                if (remove(path)) {
 +                    MYLOGE("Error removing anrd_trace file %s: %s", path, strerror(errno));
 +                }
 +                return true;
 +            }
 +        } else {
 +            MYLOGE("Can't stats any trace file under %s\n", trace_path);
 +        }
 +    }
 +    return false;
 +}
 +
  static void dump_systrace() {
-     if (!zip_writer) {
-         MYLOGD("Not dumping systrace because zip_writer is not set\n");
+     if (!is_zipping()) {
+         MYLOGD("Not dumping systrace because dumpstate is not zipping\n");
          return;
      }
      std::string systrace_path = bugreport_dir + "/systrace-" + suffix + ".txt";