1 /* dspcrashd.c 2 ** 3 ** Copyright 2010, The Android Open Source Project 4 ** 5 ** Redistribution and use in source and binary forms, with or without 6 ** modification, are permitted provided that the following conditions are met: 7 ** * Redistributions of source code must retain the above copyright 8 ** notice, this list of conditions and the following disclaimer. 9 ** * Redistributions in binary form must reproduce the above copyright 10 ** notice, this list of conditions and the following disclaimer in the 11 ** documentation and/or other materials provided with the distribution. 12 ** * Neither the name of Google Inc. nor the names of its contributors may 13 ** be used to endorse or promote products derived from this software 14 ** without specific prior written permission. 15 ** 16 ** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR 17 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 ** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 ** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <fcntl.h> 32 #include <errno.h> 33 #include <time.h> 34 #include <sys/klog.h> 35 36 #include <cutils/properties.h> 37 38 #define KLOG_BUF_SHIFT 17 /* CONFIG_LOG_BUF_SHIFT from our kernel */ 39 #define KLOG_BUF_LEN (1 << KLOG_BUF_SHIFT) 40 41 char *props[] = { 42 "ro.product.name", 43 "ro.build.id", 44 "ro.build.date", 45 "ro.serialno", 46 "ro.baseband", 47 0, 48 }; 49 50 char *dashes = "---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n"; 51 52 void dump_dmesg(int fd) 53 { 54 char buffer[KLOG_BUF_LEN + 1]; 55 char *p = buffer; 56 ssize_t ret; 57 int n, op; 58 59 n = klogctl(KLOG_READ_ALL, buffer, KLOG_BUF_LEN); 60 if (n < 0) 61 return; 62 buffer[n] = '\0'; 63 64 while((ret = write(fd, p, n))) { 65 if (ret < 0) { 66 if (errno == EINTR) 67 continue; 68 return; 69 } 70 p += ret; 71 n -= ret; 72 } 73 74 return 0; 75 } 76 77 void dump_info(int fd) 78 { 79 char buf[4096]; 80 char val[PROPERTY_VALUE_MAX]; 81 char **p = props; 82 83 write(fd, dashes, strlen(dashes)); 84 while (*p) { 85 property_get(*p,val,""); 86 sprintf(buf,"%s: %s\n", *p, val); 87 write(fd, buf, strlen(buf)); 88 p++; 89 } 90 write(fd, dashes, strlen(dashes)); 91 dump_dmesg(fd); 92 write(fd, dashes, strlen(dashes)); 93 } 94 95 void dump_dsp_state(int dsp) 96 { 97 int fd, r; 98 char name[128]; 99 char buf[128*1024]; 100 101 sprintf(name,"/sdcard/dsp.crash.%d.img", (int) time(0)); 102 103 fd = open(name, O_CREAT | O_TRUNC | O_WRONLY, 0644); 104 if (fd < 0) 105 return; 106 107 for (;;) { 108 r = read(dsp, buf, sizeof(buf)); 109 if (r == 0) break; 110 if (r < 0) { 111 if (errno == EINTR) 112 continue; 113 break; 114 } 115 write(fd, buf, r); 116 } 117 118 dump_info(fd); 119 close(fd); 120 121 fd = open("/dev/kmsg", O_WRONLY); 122 if (fd >= 0) { 123 sprintf(buf,"*** WROTE DSP RAMDUMP TO %s ***\n",name); 124 write(fd, buf, strlen(buf)); 125 close(fd); 126 } 127 } 128 129 int main(int argc, char **argv) 130 { 131 int fd; 132 fd = open("/dev/dsp_debug", O_RDWR); 133 if (fd < 0) 134 return -1; 135 136 write(fd, "wait-for-crash", 14); 137 138 dump_dsp_state(fd); 139 140 sync(); 141 sync(); 142 sync(); 143 144 write(fd, "continue-crash", 14); 145 146 close(fd); 147 148 for (;;) 149 sleep(100); 150 151 return 0; 152 } 153 154