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 41char *props[] = { 42 "ro.product.name", 43 "ro.build.id", 44 "ro.build.date", 45 "ro.serialno", 46 "ro.baseband", 47 0, 48}; 49 50char *dashes = "---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n"; 51 52void 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 77void 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 95void 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 129int 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