utils.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. /*
  2. * Copyright (C) 2008 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. #include <dirent.h>
  17. #include <errno.h>
  18. #include <fcntl.h>
  19. #include <limits.h>
  20. #include <poll.h>
  21. #include <signal.h>
  22. #include <stdarg.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <sys/inotify.h>
  27. #include <sys/stat.h>
  28. #include <sys/time.h>
  29. #include <sys/wait.h>
  30. #include <sys/klog.h>
  31. #include <time.h>
  32. #include <unistd.h>
  33. #include <sys/prctl.h>
  34. #include <cutils/debugger.h>
  35. #include <cutils/properties.h>
  36. #include <cutils/sockets.h>
  37. #include <private/android_filesystem_config.h>
  38. #include <selinux/android.h>
  39. #include "dumpstate.h"
  40. static const int64_t NANOS_PER_SEC = 1000000000;
  41. /* list of native processes to include in the native dumps */
  42. static const char* native_processes_to_dump[] = {
  43. "/system/bin/drmserver",
  44. "/system/bin/mediaserver",
  45. "/system/bin/sdcard",
  46. "/system/bin/surfaceflinger",
  47. NULL,
  48. };
  49. static uint64_t nanotime() {
  50. struct timespec ts;
  51. clock_gettime(CLOCK_MONOTONIC, &ts);
  52. return (uint64_t)ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
  53. }
  54. void for_each_userid(void (*func)(int), const char *header) {
  55. DIR *d;
  56. struct dirent *de;
  57. if (header) printf("\n------ %s ------\n", header);
  58. func(0);
  59. if (!(d = opendir("/data/system/users"))) {
  60. printf("Failed to open /data/system/users (%s)\n", strerror(errno));
  61. return;
  62. }
  63. while ((de = readdir(d))) {
  64. int userid;
  65. if (de->d_type != DT_DIR || !(userid = atoi(de->d_name))) {
  66. continue;
  67. }
  68. func(userid);
  69. }
  70. closedir(d);
  71. }
  72. static void __for_each_pid(void (*helper)(int, const char *, void *), const char *header, void *arg) {
  73. DIR *d;
  74. struct dirent *de;
  75. if (!(d = opendir("/proc"))) {
  76. printf("Failed to open /proc (%s)\n", strerror(errno));
  77. return;
  78. }
  79. printf("\n------ %s ------\n", header);
  80. while ((de = readdir(d))) {
  81. int pid;
  82. int fd;
  83. char cmdpath[255];
  84. char cmdline[255];
  85. if (!(pid = atoi(de->d_name))) {
  86. continue;
  87. }
  88. sprintf(cmdpath,"/proc/%d/cmdline", pid);
  89. memset(cmdline, 0, sizeof(cmdline));
  90. if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY | O_CLOEXEC))) < 0) {
  91. strcpy(cmdline, "N/A");
  92. } else {
  93. read(fd, cmdline, sizeof(cmdline) - 1);
  94. close(fd);
  95. }
  96. helper(pid, cmdline, arg);
  97. }
  98. closedir(d);
  99. }
  100. static void for_each_pid_helper(int pid, const char *cmdline, void *arg) {
  101. for_each_pid_func *func = arg;
  102. func(pid, cmdline);
  103. }
  104. void for_each_pid(for_each_pid_func func, const char *header) {
  105. __for_each_pid(for_each_pid_helper, header, func);
  106. }
  107. static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
  108. DIR *d;
  109. struct dirent *de;
  110. char taskpath[255];
  111. for_each_tid_func *func = arg;
  112. sprintf(taskpath, "/proc/%d/task", pid);
  113. if (!(d = opendir(taskpath))) {
  114. printf("Failed to open %s (%s)\n", taskpath, strerror(errno));
  115. return;
  116. }
  117. func(pid, pid, cmdline);
  118. while ((de = readdir(d))) {
  119. int tid;
  120. int fd;
  121. char commpath[255];
  122. char comm[255];
  123. if (!(tid = atoi(de->d_name))) {
  124. continue;
  125. }
  126. if (tid == pid)
  127. continue;
  128. sprintf(commpath,"/proc/%d/comm", tid);
  129. memset(comm, 0, sizeof(comm));
  130. if ((fd = TEMP_FAILURE_RETRY(open(commpath, O_RDONLY | O_CLOEXEC))) < 0) {
  131. strcpy(comm, "N/A");
  132. } else {
  133. char *c;
  134. read(fd, comm, sizeof(comm) - 1);
  135. close(fd);
  136. c = strrchr(comm, '\n');
  137. if (c) {
  138. *c = '\0';
  139. }
  140. }
  141. func(pid, tid, comm);
  142. }
  143. closedir(d);
  144. }
  145. void for_each_tid(for_each_tid_func func, const char *header) {
  146. __for_each_pid(for_each_tid_helper, header, func);
  147. }
  148. void show_wchan(int pid, int tid, const char *name) {
  149. char path[255];
  150. char buffer[255];
  151. int fd;
  152. char name_buffer[255];
  153. memset(buffer, 0, sizeof(buffer));
  154. sprintf(path, "/proc/%d/wchan", tid);
  155. if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
  156. printf("Failed to open '%s' (%s)\n", path, strerror(errno));
  157. return;
  158. }
  159. if (read(fd, buffer, sizeof(buffer)) < 0) {
  160. printf("Failed to read '%s' (%s)\n", path, strerror(errno));
  161. goto out_close;
  162. }
  163. snprintf(name_buffer, sizeof(name_buffer), "%*s%s",
  164. pid == tid ? 0 : 3, "", name);
  165. printf("%-7d %-32s %s\n", tid, name_buffer, buffer);
  166. out_close:
  167. close(fd);
  168. return;
  169. }
  170. void do_dmesg() {
  171. printf("------ KERNEL LOG (dmesg) ------\n");
  172. /* Get size of kernel buffer */
  173. int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
  174. if (size <= 0) {
  175. printf("Unexpected klogctl return value: %d\n\n", size);
  176. return;
  177. }
  178. char *buf = (char *) malloc(size + 1);
  179. if (buf == NULL) {
  180. printf("memory allocation failed\n\n");
  181. return;
  182. }
  183. int retval = klogctl(KLOG_READ_ALL, buf, size);
  184. if (retval < 0) {
  185. printf("klogctl failure\n\n");
  186. free(buf);
  187. return;
  188. }
  189. buf[retval] = '\0';
  190. printf("%s\n\n", buf);
  191. free(buf);
  192. return;
  193. }
  194. void do_showmap(int pid, const char *name) {
  195. char title[255];
  196. char arg[255];
  197. sprintf(title, "SHOW MAP %d (%s)", pid, name);
  198. sprintf(arg, "%d", pid);
  199. run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
  200. }
  201. static int _dump_file_from_fd(const char *title, const char *path, int fd) {
  202. if (title) printf("------ %s (%s", title, path);
  203. if (title) {
  204. struct stat st;
  205. if (memcmp(path, "/proc/", 6) && memcmp(path, "/sys/", 5) && !fstat(fd, &st)) {
  206. char stamp[80];
  207. time_t mtime = st.st_mtime;
  208. strftime(stamp, sizeof(stamp), "%Y-%m-%d %H:%M:%S", localtime(&mtime));
  209. printf(": %s", stamp);
  210. }
  211. printf(") ------\n");
  212. }
  213. bool newline = false;
  214. fd_set read_set;
  215. struct timeval tm;
  216. while (1) {
  217. FD_ZERO(&read_set);
  218. FD_SET(fd, &read_set);
  219. /* Timeout if no data is read for 30 seconds. */
  220. tm.tv_sec = 30;
  221. tm.tv_usec = 0;
  222. uint64_t elapsed = nanotime();
  223. int ret = TEMP_FAILURE_RETRY(select(fd + 1, &read_set, NULL, NULL, &tm));
  224. if (ret == -1) {
  225. printf("*** %s: select failed: %s\n", path, strerror(errno));
  226. newline = true;
  227. break;
  228. } else if (ret == 0) {
  229. elapsed = nanotime() - elapsed;
  230. printf("*** %s: Timed out after %.3fs\n", path,
  231. (float) elapsed / NANOS_PER_SEC);
  232. newline = true;
  233. break;
  234. } else {
  235. char buffer[65536];
  236. ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
  237. if (bytes_read > 0) {
  238. fwrite(buffer, bytes_read, 1, stdout);
  239. newline = (buffer[bytes_read-1] == '\n');
  240. } else {
  241. if (bytes_read == -1) {
  242. printf("*** %s: Failed to read from fd: %s", path, strerror(errno));
  243. newline = true;
  244. }
  245. break;
  246. }
  247. }
  248. }
  249. close(fd);
  250. if (!newline) printf("\n");
  251. if (title) printf("\n");
  252. return 0;
  253. }
  254. /* prints the contents of a file */
  255. int dump_file(const char *title, const char *path) {
  256. int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
  257. if (fd < 0) {
  258. int err = errno;
  259. if (title) printf("------ %s (%s) ------\n", title, path);
  260. printf("*** %s: %s\n", path, strerror(err));
  261. if (title) printf("\n");
  262. return -1;
  263. }
  264. return _dump_file_from_fd(title, path, fd);
  265. }
  266. /* calls skip to gate calling dump_from_fd recursively
  267. * in the specified directory. dump_from_fd defaults to
  268. * dump_file_from_fd above when set to NULL. skip defaults
  269. * to false when set to NULL. dump_from_fd will always be
  270. * called with title NULL.
  271. */
  272. int dump_files(const char *title, const char *dir,
  273. bool (*skip)(const char *path),
  274. int (*dump_from_fd)(const char *title, const char *path, int fd)) {
  275. DIR *dirp;
  276. struct dirent *d;
  277. char *newpath = NULL;
  278. char *slash = "/";
  279. int fd, retval = 0;
  280. if (title) {
  281. printf("------ %s (%s) ------\n", title, dir);
  282. }
  283. if (dir[strlen(dir) - 1] == '/') {
  284. ++slash;
  285. }
  286. dirp = opendir(dir);
  287. if (dirp == NULL) {
  288. retval = -errno;
  289. fprintf(stderr, "%s: %s\n", dir, strerror(errno));
  290. return retval;
  291. }
  292. if (!dump_from_fd) {
  293. dump_from_fd = dump_file_from_fd;
  294. }
  295. for (; ((d = readdir(dirp))); free(newpath), newpath = NULL) {
  296. if ((d->d_name[0] == '.')
  297. && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
  298. || (d->d_name[1] == '\0'))) {
  299. continue;
  300. }
  301. asprintf(&newpath, "%s%s%s%s", dir, slash, d->d_name,
  302. (d->d_type == DT_DIR) ? "/" : "");
  303. if (!newpath) {
  304. retval = -errno;
  305. continue;
  306. }
  307. if (skip && (*skip)(newpath)) {
  308. continue;
  309. }
  310. if (d->d_type == DT_DIR) {
  311. int ret = dump_files(NULL, newpath, skip, dump_from_fd);
  312. if (ret < 0) {
  313. retval = ret;
  314. }
  315. continue;
  316. }
  317. fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
  318. if (fd < 0) {
  319. retval = fd;
  320. printf("*** %s: %s\n", newpath, strerror(errno));
  321. continue;
  322. }
  323. (*dump_from_fd)(NULL, newpath, fd);
  324. }
  325. closedir(dirp);
  326. if (title) {
  327. printf("\n");
  328. }
  329. return retval;
  330. }
  331. /* fd must have been opened with the flag O_NONBLOCK. With this flag set,
  332. * it's possible to avoid issues where opening the file itself can get
  333. * stuck.
  334. */
  335. int dump_file_from_fd(const char *title, const char *path, int fd) {
  336. int flags = fcntl(fd, F_GETFL);
  337. if (flags == -1) {
  338. printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
  339. return -1;
  340. } else if (!(flags & O_NONBLOCK)) {
  341. printf("*** %s: fd must have O_NONBLOCK set.\n", path);
  342. return -1;
  343. }
  344. return _dump_file_from_fd(title, path, fd);
  345. }
  346. bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
  347. sigset_t child_mask, old_mask;
  348. sigemptyset(&child_mask);
  349. sigaddset(&child_mask, SIGCHLD);
  350. if (sigprocmask(SIG_BLOCK, &child_mask, &old_mask) == -1) {
  351. printf("*** sigprocmask failed: %s\n", strerror(errno));
  352. return false;
  353. }
  354. struct timespec ts;
  355. ts.tv_sec = timeout_seconds;
  356. ts.tv_nsec = 0;
  357. int ret = TEMP_FAILURE_RETRY(sigtimedwait(&child_mask, NULL, &ts));
  358. int saved_errno = errno;
  359. // Set the signals back the way they were.
  360. if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1) {
  361. printf("*** sigprocmask failed: %s\n", strerror(errno));
  362. if (ret == 0) {
  363. return false;
  364. }
  365. }
  366. if (ret == -1) {
  367. errno = saved_errno;
  368. if (errno == EAGAIN) {
  369. errno = ETIMEDOUT;
  370. } else {
  371. printf("*** sigtimedwait failed: %s\n", strerror(errno));
  372. }
  373. return false;
  374. }
  375. pid_t child_pid = waitpid(pid, status, WNOHANG);
  376. if (child_pid != pid) {
  377. if (child_pid != -1) {
  378. printf("*** Waiting for pid %d, got pid %d instead\n", pid, child_pid);
  379. } else {
  380. printf("*** waitpid failed: %s\n", strerror(errno));
  381. }
  382. return false;
  383. }
  384. return true;
  385. }
  386. /* forks a command and waits for it to finish */
  387. int run_command(const char *title, int timeout_seconds, const char *command, ...) {
  388. fflush(stdout);
  389. uint64_t start = nanotime();
  390. pid_t pid = fork();
  391. /* handle error case */
  392. if (pid < 0) {
  393. printf("*** fork: %s\n", strerror(errno));
  394. return pid;
  395. }
  396. /* handle child case */
  397. if (pid == 0) {
  398. const char *args[1024] = {command};
  399. size_t arg;
  400. /* make sure the child dies when dumpstate dies */
  401. prctl(PR_SET_PDEATHSIG, SIGKILL);
  402. /* just ignore SIGPIPE, will go down with parent's */
  403. struct sigaction sigact;
  404. memset(&sigact, 0, sizeof(sigact));
  405. sigact.sa_handler = SIG_IGN;
  406. sigaction(SIGPIPE, &sigact, NULL);
  407. va_list ap;
  408. va_start(ap, command);
  409. if (title) printf("------ %s (%s", title, command);
  410. for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
  411. args[arg] = va_arg(ap, const char *);
  412. if (args[arg] == NULL) break;
  413. if (title) printf(" %s", args[arg]);
  414. }
  415. if (title) printf(") ------\n");
  416. fflush(stdout);
  417. execvp(command, (char**) args);
  418. printf("*** exec(%s): %s\n", command, strerror(errno));
  419. fflush(stdout);
  420. _exit(-1);
  421. }
  422. /* handle parent case */
  423. int status;
  424. bool ret = waitpid_with_timeout(pid, timeout_seconds, &status);
  425. uint64_t elapsed = nanotime() - start;
  426. if (!ret) {
  427. if (errno == ETIMEDOUT) {
  428. printf("*** %s: Timed out after %.3fs (killing pid %d)\n", command,
  429. (float) elapsed / NANOS_PER_SEC, pid);
  430. } else {
  431. printf("*** %s: Error after %.4fs (killing pid %d)\n", command,
  432. (float) elapsed / NANOS_PER_SEC, pid);
  433. }
  434. kill(pid, SIGTERM);
  435. if (!waitpid_with_timeout(pid, 5, NULL)) {
  436. kill(pid, SIGKILL);
  437. if (!waitpid_with_timeout(pid, 5, NULL)) {
  438. printf("*** %s: Cannot kill %d even with SIGKILL.\n", command, pid);
  439. }
  440. }
  441. return -1;
  442. }
  443. if (WIFSIGNALED(status)) {
  444. printf("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
  445. } else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
  446. printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
  447. }
  448. if (title) printf("[%s: %.3fs elapsed]\n\n", command, (float)elapsed / NANOS_PER_SEC);
  449. return status;
  450. }
  451. size_t num_props = 0;
  452. static char* props[2000];
  453. static void print_prop(const char *key, const char *name, void *user) {
  454. (void) user;
  455. if (num_props < sizeof(props) / sizeof(props[0])) {
  456. char buf[PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 10];
  457. snprintf(buf, sizeof(buf), "[%s]: [%s]\n", key, name);
  458. props[num_props++] = strdup(buf);
  459. }
  460. }
  461. static int compare_prop(const void *a, const void *b) {
  462. return strcmp(*(char * const *) a, *(char * const *) b);
  463. }
  464. /* prints all the system properties */
  465. void print_properties() {
  466. size_t i;
  467. num_props = 0;
  468. property_list(print_prop, NULL);
  469. qsort(&props, num_props, sizeof(props[0]), compare_prop);
  470. printf("------ SYSTEM PROPERTIES ------\n");
  471. for (i = 0; i < num_props; ++i) {
  472. fputs(props[i], stdout);
  473. free(props[i]);
  474. }
  475. printf("\n");
  476. }
  477. /* redirect output to a service control socket */
  478. void redirect_to_socket(FILE *redirect, const char *service) {
  479. int s = android_get_control_socket(service);
  480. if (s < 0) {
  481. fprintf(stderr, "android_get_control_socket(%s): %s\n", service, strerror(errno));
  482. exit(1);
  483. }
  484. fcntl(s, F_SETFD, FD_CLOEXEC);
  485. if (listen(s, 4) < 0) {
  486. fprintf(stderr, "listen(control socket): %s\n", strerror(errno));
  487. exit(1);
  488. }
  489. struct sockaddr addr;
  490. socklen_t alen = sizeof(addr);
  491. int fd = accept(s, &addr, &alen);
  492. if (fd < 0) {
  493. fprintf(stderr, "accept(control socket): %s\n", strerror(errno));
  494. exit(1);
  495. }
  496. fflush(redirect);
  497. dup2(fd, fileno(redirect));
  498. close(fd);
  499. }
  500. /* redirect output to a file */
  501. void redirect_to_file(FILE *redirect, char *path) {
  502. char *chp = path;
  503. /* skip initial slash */
  504. if (chp[0] == '/')
  505. chp++;
  506. /* create leading directories, if necessary */
  507. while (chp && chp[0]) {
  508. chp = strchr(chp, '/');
  509. if (chp) {
  510. *chp = 0;
  511. mkdir(path, 0770); /* drwxrwx--- */
  512. *chp++ = '/';
  513. }
  514. }
  515. int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
  516. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
  517. if (fd < 0) {
  518. fprintf(stderr, "%s: %s\n", path, strerror(errno));
  519. exit(1);
  520. }
  521. TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect)));
  522. close(fd);
  523. }
  524. static bool should_dump_native_traces(const char* path) {
  525. for (const char** p = native_processes_to_dump; *p; p++) {
  526. if (!strcmp(*p, path)) {
  527. return true;
  528. }
  529. }
  530. return false;
  531. }
  532. /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
  533. const char *dump_traces() {
  534. const char* result = NULL;
  535. char traces_path[PROPERTY_VALUE_MAX] = "";
  536. property_get("dalvik.vm.stack-trace-file", traces_path, "");
  537. if (!traces_path[0]) return NULL;
  538. /* move the old traces.txt (if any) out of the way temporarily */
  539. char anr_traces_path[PATH_MAX];
  540. strlcpy(anr_traces_path, traces_path, sizeof(anr_traces_path));
  541. strlcat(anr_traces_path, ".anr", sizeof(anr_traces_path));
  542. if (rename(traces_path, anr_traces_path) && errno != ENOENT) {
  543. fprintf(stderr, "rename(%s, %s): %s\n", traces_path, anr_traces_path, strerror(errno));
  544. return NULL; // Can't rename old traces.txt -- no permission? -- leave it alone instead
  545. }
  546. /* make the directory if necessary */
  547. char anr_traces_dir[PATH_MAX];
  548. strlcpy(anr_traces_dir, traces_path, sizeof(anr_traces_dir));
  549. char *slash = strrchr(anr_traces_dir, '/');
  550. if (slash != NULL) {
  551. *slash = '\0';
  552. if (!mkdir(anr_traces_dir, 0775)) {
  553. chown(anr_traces_dir, AID_SYSTEM, AID_SYSTEM);
  554. chmod(anr_traces_dir, 0775);
  555. if (selinux_android_restorecon(anr_traces_dir, 0) == -1) {
  556. fprintf(stderr, "restorecon failed for %s: %s\n", anr_traces_dir, strerror(errno));
  557. }
  558. } else if (errno != EEXIST) {
  559. fprintf(stderr, "mkdir(%s): %s\n", anr_traces_dir, strerror(errno));
  560. return NULL;
  561. }
  562. }
  563. /* create a new, empty traces.txt file to receive stack dumps */
  564. int fd = TEMP_FAILURE_RETRY(open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
  565. 0666)); /* -rw-rw-rw- */
  566. if (fd < 0) {
  567. fprintf(stderr, "%s: %s\n", traces_path, strerror(errno));
  568. return NULL;
  569. }
  570. int chmod_ret = fchmod(fd, 0666);
  571. if (chmod_ret < 0) {
  572. fprintf(stderr, "fchmod on %s failed: %s\n", traces_path, strerror(errno));
  573. close(fd);
  574. return NULL;
  575. }
  576. /* walk /proc and kill -QUIT all Dalvik processes */
  577. DIR *proc = opendir("/proc");
  578. if (proc == NULL) {
  579. fprintf(stderr, "/proc: %s\n", strerror(errno));
  580. goto error_close_fd;
  581. }
  582. /* use inotify to find when processes are done dumping */
  583. int ifd = inotify_init();
  584. if (ifd < 0) {
  585. fprintf(stderr, "inotify_init: %s\n", strerror(errno));
  586. goto error_close_fd;
  587. }
  588. int wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE);
  589. if (wfd < 0) {
  590. fprintf(stderr, "inotify_add_watch(%s): %s\n", traces_path, strerror(errno));
  591. goto error_close_ifd;
  592. }
  593. struct dirent *d;
  594. int dalvik_found = 0;
  595. while ((d = readdir(proc))) {
  596. int pid = atoi(d->d_name);
  597. if (pid <= 0) continue;
  598. char path[PATH_MAX];
  599. char data[PATH_MAX];
  600. snprintf(path, sizeof(path), "/proc/%d/exe", pid);
  601. ssize_t len = readlink(path, data, sizeof(data) - 1);
  602. if (len <= 0) {
  603. continue;
  604. }
  605. data[len] = '\0';
  606. if (!strncmp(data, "/system/bin/app_process", strlen("/system/bin/app_process"))) {
  607. /* skip zygote -- it won't dump its stack anyway */
  608. snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
  609. int cfd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC));
  610. len = read(cfd, data, sizeof(data) - 1);
  611. close(cfd);
  612. if (len <= 0) {
  613. continue;
  614. }
  615. data[len] = '\0';
  616. if (!strncmp(data, "zygote", strlen("zygote"))) {
  617. continue;
  618. }
  619. ++dalvik_found;
  620. uint64_t start = nanotime();
  621. if (kill(pid, SIGQUIT)) {
  622. fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
  623. continue;
  624. }
  625. /* wait for the writable-close notification from inotify */
  626. struct pollfd pfd = { ifd, POLLIN, 0 };
  627. int ret = poll(&pfd, 1, 5000); /* 5 sec timeout */
  628. if (ret < 0) {
  629. fprintf(stderr, "poll: %s\n", strerror(errno));
  630. } else if (ret == 0) {
  631. fprintf(stderr, "warning: timed out dumping pid %d\n", pid);
  632. } else {
  633. struct inotify_event ie;
  634. read(ifd, &ie, sizeof(ie));
  635. }
  636. if (lseek(fd, 0, SEEK_END) < 0) {
  637. fprintf(stderr, "lseek: %s\n", strerror(errno));
  638. } else {
  639. dprintf(fd, "[dump dalvik stack %d: %.3fs elapsed]\n",
  640. pid, (float)(nanotime() - start) / NANOS_PER_SEC);
  641. }
  642. } else if (should_dump_native_traces(data)) {
  643. /* dump native process if appropriate */
  644. if (lseek(fd, 0, SEEK_END) < 0) {
  645. fprintf(stderr, "lseek: %s\n", strerror(errno));
  646. } else {
  647. static uint16_t timeout_failures = 0;
  648. uint64_t start = nanotime();
  649. /* If 3 backtrace dumps fail in a row, consider debuggerd dead. */
  650. if (timeout_failures == 3) {
  651. dprintf(fd, "too many stack dump failures, skipping...\n");
  652. } else if (dump_backtrace_to_file_timeout(pid, fd, 20) == -1) {
  653. dprintf(fd, "dumping failed, likely due to a timeout\n");
  654. timeout_failures++;
  655. } else {
  656. timeout_failures = 0;
  657. }
  658. dprintf(fd, "[dump native stack %d: %.3fs elapsed]\n",
  659. pid, (float)(nanotime() - start) / NANOS_PER_SEC);
  660. }
  661. }
  662. }
  663. if (dalvik_found == 0) {
  664. fprintf(stderr, "Warning: no Dalvik processes found to dump stacks\n");
  665. }
  666. static char dump_traces_path[PATH_MAX];
  667. strlcpy(dump_traces_path, traces_path, sizeof(dump_traces_path));
  668. strlcat(dump_traces_path, ".bugreport", sizeof(dump_traces_path));
  669. if (rename(traces_path, dump_traces_path)) {
  670. fprintf(stderr, "rename(%s, %s): %s\n", traces_path, dump_traces_path, strerror(errno));
  671. goto error_close_ifd;
  672. }
  673. result = dump_traces_path;
  674. /* replace the saved [ANR] traces.txt file */
  675. rename(anr_traces_path, traces_path);
  676. error_close_ifd:
  677. close(ifd);
  678. error_close_fd:
  679. close(fd);
  680. return result;
  681. }
  682. void dump_route_tables() {
  683. const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
  684. dump_file("RT_TABLES", RT_TABLES_PATH);
  685. FILE* fp = fopen(RT_TABLES_PATH, "re");
  686. if (!fp) {
  687. printf("*** %s: %s\n", RT_TABLES_PATH, strerror(errno));
  688. return;
  689. }
  690. char table[16];
  691. // Each line has an integer (the table number), a space, and a string (the table name). We only
  692. // need the table number. It's a 32-bit unsigned number, so max 10 chars. Skip the table name.
  693. // Add a fixed max limit so this doesn't go awry.
  694. for (int i = 0; i < 64 && fscanf(fp, " %10s %*s", table) == 1; ++i) {
  695. run_command("ROUTE TABLE IPv4", 10, "ip", "-4", "route", "show", "table", table, NULL);
  696. run_command("ROUTE TABLE IPv6", 10, "ip", "-6", "route", "show", "table", table, NULL);
  697. }
  698. fclose(fp);
  699. }