summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShanmugam Vasudevan <Shanmugam.Vasudevan@knowles.com>2019-06-24 18:55:24 -0700
committerJuyu Chen <juyuchen@google.com>2019-07-18 10:26:02 -0700
commit459085d8328af6b650a9726e84e8105484a7851e (patch)
tree7dd96115f89ad0d6a58a8d17ddaa81bd3b61a1e4
parentd99ddd71f5b3ab9e0b6ced7ffbf42f7a3e186a8b (diff)
downloadandroid_hardware_knowles_athletico_sound_trigger_hal-459085d8328af6b650a9726e84e8105484a7851e.tar.gz
android_hardware_knowles_athletico_sound_trigger_hal-459085d8328af6b650a9726e84e8105484a7851e.tar.bz2
android_hardware_knowles_athletico_sound_trigger_hal-459085d8328af6b650a9726e84e8105484a7851e.zip
sthal: Log crash and core-dump signature
+Get the Crash reason as part of the crash_dump buffer from kernel and write it to file +Added crash_dump analyzer and concatenate the analyzer's output to the crash reason file. +Fix crash dump analyzer to parse 64-bit timestamp in FW logs. Bug: 135634349 Test: verify crash reason Change-Id: Iaccdb8eb10ed73ae2543c996e0840e2f4a5a2253 Signed-off-by: Shanmugam Vasudevan <Shanmugam.Vasudevan@knowles.com> Signed-off-by: Juyu Chen <juyuchen@google.com>
-rw-r--r--Android.mk2
-rw-r--r--tests/crash_analyzer.c252
-rw-r--r--tests/crash_analyzer.h10
-rw-r--r--tests/crash_analyzer_defs.h228
-rwxr-xr-xtests/crash_event_logger.c202
5 files changed, 656 insertions, 38 deletions
diff --git a/Android.mk b/Android.mk
index 74f85de..75e6358 100644
--- a/Android.mk
+++ b/Android.mk
@@ -226,7 +226,7 @@ include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE := crash_event_logger
-LOCAL_SRC_FILES := tests/crash_event_logger.c
+LOCAL_SRC_FILES := tests/crash_event_logger.c tests/crash_analyzer.c
LOCAL_32_BIT_ONLY := true
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_MODULE_TAGS := optional
diff --git a/tests/crash_analyzer.c b/tests/crash_analyzer.c
new file mode 100644
index 0000000..d413a22
--- /dev/null
+++ b/tests/crash_analyzer.c
@@ -0,0 +1,252 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include <cutils/log.h>
+
+#include "crash_analyzer_defs.h"
+#include "crash_analyzer.h"
+
+#define MAX_PATTERN_SIZE 1024
+#define MAX_CSTRING_SIZE 8000
+#define SEPARATOR " | "
+
+int find_rightmost_setbit_position(uint32_t number)
+{
+ if (number)
+ return log2(number ^ (number & (number - 1)));
+
+ return -1;
+}
+
+char* find_exception_in_hmd_dmx(unsigned char *buf, int buf_len,
+ const char *core, char *outbuf,
+ int outbuf_max_size)
+{
+ char exccause[64] = {0};
+ char epc1[32] = {0};
+ uint32_t *wordBuf = (uint32_t*)buf;
+
+ if (buf == NULL || buf_len < HMD_DMX_INDEX_MAX * BYTES_PER_WORD ||
+ core == NULL || outbuf == NULL || outbuf_max_size <= 0 ||
+ wordBuf[START_HMD_DMX_INDEX] == 0 ||
+ strlen(outbuf) >= outbuf_max_size)
+ return outbuf;
+
+ int excepIndex = wordBuf[EXCEPTION_INDEX];
+
+ if (excepIndex >= HMD_DMXEXCEPTIONCAUSELIST_SIZE) {
+ strncpy(exccause, "Reserved", sizeof(exccause));
+ }
+ else {
+ strncpy(exccause, Hmd_DmxExceptionCauseList[excepIndex],
+ sizeof(exccause));
+ }
+
+ snprintf(epc1, sizeof(epc1), "0x%08x", wordBuf[EPC1_INDEX]);
+
+ if (strlen(outbuf) > 0) {
+ strncat(outbuf, SEPARATOR,
+ outbuf_max_size - strlen(outbuf) - 1);
+ }
+
+ strncat(outbuf, core,
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, " crash ",
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, exccause,
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, "/",
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, epc1,
+ outbuf_max_size - strlen(outbuf) - 1);
+
+ return outbuf;
+}
+
+char* find_exceptionin_cm4(unsigned char *buf, int buf_len, const char *core,
+ char *outbuf, int outbuf_max_size)
+{
+
+ char cause[64] = {0};
+ uint32_t *wordBuf = (uint32_t*)buf;
+
+ if (buf == NULL || buf_len < CM4_INDEX_MAX * BYTES_PER_WORD ||
+ core == NULL || outbuf == NULL || outbuf_max_size <= 0 ||
+ wordBuf[START_CM4_INDEX] == 0 ||
+ strlen(outbuf) >= outbuf_max_size)
+ return outbuf;
+
+ int faultStatusRegister = wordBuf[FAULT_STATUS_INDEX];
+
+ int exceptionBitSet = find_rightmost_setbit_position(faultStatusRegister);
+
+ if (exceptionBitSet == -1) {
+ return outbuf;
+ }
+
+ if (exceptionBitSet >= CM4EXCEPTIONCAUSELIST_SIZE) {
+ strncpy(cause, "Reserved", sizeof(cause));
+ }
+ else {
+ strncpy(cause, Cm4ExceptionCauseList[exceptionBitSet],
+ sizeof(cause));
+ }
+
+ if(strlen(outbuf) > 0){
+ strncat(outbuf, SEPARATOR,
+ outbuf_max_size - strlen(outbuf) - 1);
+ }
+
+ strncat(outbuf, core,
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, " crash ",
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, cause,
+ outbuf_max_size - strlen(outbuf) - 1);
+
+ return outbuf;
+}
+
+
+char* find_fatal_assert(unsigned char *buf, int buf_len, int size,
+ const char *core, char *outbuf,
+ int outbuf_max_size)
+{
+
+ char cause[64] = {0};
+ char lineNumStr[10] = {0};
+ uint32_t *wordBuf = (uint32_t*)buf;
+ uint32_t wordSize = size / 4;
+ /*
+ *|Time Stamp|Event Label,Debug Level,Line No|Opaque Data 1|Opaque Data 2|Opaque Data 3|Opaque Data 4|
+ *|(64 bits) | (12 bits), (4 bits), (16 bits)| (32 bits) | (32 bits) | (32 bits) | (32 bits) |
+ */
+ int info_size = 7;
+ /* Index of event label word in 64 bit timestamp */
+ int curEvtIndex = 2;
+
+ if (buf == NULL || size <= 0 || buf_len < size || core == NULL ||
+ outbuf == NULL || outbuf_max_size <= 0 ||
+ strlen(outbuf) >= outbuf_max_size)
+ return outbuf;
+
+ /* This 32-bit word containing this info
+ * is in Little-Endian format to read
+ * the value of this fields.
+ *
+ * |0...11| -> Module Id
+ * |12...15| -> Log level
+ * |16...31| -> Line no
+ */
+ while (curEvtIndex < wordSize) {
+ int evt = wordBuf[curEvtIndex];
+ int logLevel = (evt >> 12) & 0xF;
+
+ if (logLevel != DBG_LOG_LVL_FATAL) {
+ curEvtIndex += info_size;
+ continue;
+ }
+
+ int module_id = evt & 0xFFF;
+ int lineNo = (evt >> 16) & 0xFFFF;
+
+ if (module_id >= ASSERTDEBUGMODLIST_SIZE) {
+ /* Invalid module id */
+ curEvtIndex += info_size;
+ continue;
+ }
+ else {
+ snprintf(cause, sizeof(cause), "%s",
+ AssertDebugModList[module_id]);
+ }
+
+ strncat(cause , "+",
+ sizeof(cause) - strlen(cause) - 1);
+
+ snprintf(lineNumStr, sizeof(lineNumStr), "%d", lineNo);
+
+ strncat(cause, lineNumStr,
+ sizeof(cause) - strlen(cause) - 1);
+
+ if(strlen(outbuf) > 0) {
+ strncat(outbuf, SEPARATOR,
+ outbuf_max_size - strlen(outbuf) - 1);
+ }
+
+ strncat(outbuf, "ASSERT LOG in ",
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, core,
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, " ",
+ outbuf_max_size - strlen(outbuf) - 1);
+ strncat(outbuf, cause,
+ outbuf_max_size - strlen(outbuf) - 1);
+
+ return outbuf;
+ }
+
+ return outbuf;
+}
+
+int analyse_crash_info(const unsigned char *buf, const int buf_len,
+ char *out_crash_analyzer_str,
+ int max_out_crash_analyzer_str_size)
+{
+ unsigned int file_index = 0, size = 0, tot_len = 0;
+ int fcount = 0;
+ unsigned char *ptr = NULL;
+
+ if (buf == NULL || out_crash_analyzer_str == NULL ||
+ buf_len <= 0 || max_out_crash_analyzer_str_size <= 0) {
+ ALOGE("%s: Bad parameters", __func__);
+ return -1;
+ }
+
+ out_crash_analyzer_str[0] = '\0';
+
+ while ((tot_len + STEP_LENGTH - 1 < buf_len) && (fcount++ < FILE_MAX)) {
+ file_index = buf[tot_len];
+
+ size = buf[tot_len + 8] |
+ buf[tot_len + 9] << 8 |
+ buf[tot_len + 10] << 16 |
+ buf[tot_len + 11] << 24;
+
+ tot_len += STEP_LENGTH;
+ ptr = (unsigned char*)buf + tot_len;
+
+ if (file_index == CM4_DUMP_DEBUG) {
+ find_fatal_assert(ptr, buf_len - tot_len, size, "CM4",
+ out_crash_analyzer_str,
+ max_out_crash_analyzer_str_size);
+ } else if(file_index == HMD_DUMP_DEBUG) {
+ find_fatal_assert(ptr, buf_len - tot_len, size, "HMD",
+ out_crash_analyzer_str,
+ max_out_crash_analyzer_str_size);
+ } else if(file_index == DMX_DUMP_DEBUG) {
+ find_fatal_assert(ptr, buf_len - tot_len, size, "DMX",
+ out_crash_analyzer_str,
+ max_out_crash_analyzer_str_size);
+ } else if(file_index == CM4_DUMP_CRASH) {
+ find_exceptionin_cm4(ptr, buf_len - tot_len, "CM4",
+ out_crash_analyzer_str,
+ max_out_crash_analyzer_str_size);
+ } else if(file_index == HMD_DUMP_CRASH) {
+ find_exception_in_hmd_dmx(ptr, buf_len - tot_len, "HMD",
+ out_crash_analyzer_str,
+ max_out_crash_analyzer_str_size);
+ } else if(file_index == DMX_DUMP_CRASH) {
+ find_exception_in_hmd_dmx(ptr, buf_len - tot_len, "DMX",
+ out_crash_analyzer_str,
+ max_out_crash_analyzer_str_size);
+ } else {
+ ALOGE("%s: unknown index number: %u", __func__ , file_index);
+ }
+
+ tot_len += size;
+ }
+
+ return strlen(out_crash_analyzer_str);
+}
diff --git a/tests/crash_analyzer.h b/tests/crash_analyzer.h
new file mode 100644
index 0000000..6d05d15
--- /dev/null
+++ b/tests/crash_analyzer.h
@@ -0,0 +1,10 @@
+#ifndef _CRASH_PROCESS_H_
+#define _CRASH_PROCESS_H_
+
+#define STEP_LENGTH 12
+#define BYTES_PER_WORD 4
+
+int analyse_crash_info(const unsigned char *buf, const int buf_len,
+ char *out_crash_analyzer_str,
+ int max_out_crash_analyzer_str_size);
+#endif
diff --git a/tests/crash_analyzer_defs.h b/tests/crash_analyzer_defs.h
new file mode 100644
index 0000000..c004ac5
--- /dev/null
+++ b/tests/crash_analyzer_defs.h
@@ -0,0 +1,228 @@
+#ifndef _CRASH_ANALYZER_DEFS_H_
+#define _CRASH_ANALYZER_DEFS_H_
+
+#include <limits.h>
+#define HMD_DMXEXCEPTIONCAUSELIST_SIZE 41
+#define CM4EXCEPTIONCAUSELIST_SIZE 26
+#define ASSERTDEBUGMODLIST_SIZE 104
+
+const char* Hmd_DmxExceptionCauseList[HMD_DMXEXCEPTIONCAUSELIST_SIZE] = {
+ "IllegalInstructionCause",
+ "SyscallCause",
+ "InstructionFetchErrorCause",
+ "LoadStoreErrorCause",
+ "Level1InterruptCause",
+ "AllocaCause",
+ "IntegerDivideByZeroCause",
+ "PCValueErrorCause",
+ "PrivilegedCause",
+ "LoadStoreAlignmentCause",
+ "Reserved",
+ "Reserved",
+ "InstrPIFDataErrorCause",
+ "LoadStorePIFDataErrorCause",
+ "InstrPIFAddrErrorCause",
+ "LoadStorePIFAddrErrorCause",
+ "InstTLBMissCause",
+ "InstTLBMultiHitCause",
+ "InstFetchPrivilegeCause",
+ "Reserved",
+ "InstFetchProhibitedCause",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "LoadStoreTLBMissCause",
+ "LoadStoreTLBMultiHitCause",
+ "LoadStorePrivilegeCause",
+ "Reserved",
+ "LoadProhibitedCause",
+ "StoreProhibitedCause",
+ "Reserved",
+ "Reserved",
+ "CoprocessornDisabled",
+ "CoprocessornDisabled",
+ "CoprocessornDisabled",
+ "CoprocessornDisabled",
+ "CoprocessornDisabled",
+ "CoprocessornDisabled",
+ "CoprocessornDisabled",
+ "CoprocessornDisabled",
+ "Reserved"};
+
+const char* Cm4ExceptionCauseList[CM4EXCEPTIONCAUSELIST_SIZE] = {
+ "IACCVIOL",
+ "DACCVIOL",
+ "Reserved",
+ "MUNSTKERR",
+ "MSTKERR",
+ "MLSPERR",
+ "Reserved",
+ "MMARVALID",
+ "IBUSERR",
+ "PRECISERR",
+ "IMPRECISERR",
+ "UNSTKERR",
+ "STKERR",
+ "LSPERR",
+ "Reserved",
+ "BFARVALID",
+ "UNDEFINSTR",
+ "INVSTATE",
+ "INVPC",
+ "NOCP",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "UNALIGNED",
+ "DIVBYZERO"};
+
+const char* AssertDebugModList[ASSERTDEBUGMODLIST_SIZE] = {
+ "Invalid",
+ "DBG_MODULE_ID_ACCDETMGR_LOG = 1",
+ "DBG_MODULE_ID_BATTERYMGR_LOG",
+ "DBG_MODULE_ID_BLUETOOTHMGR_LOG",
+ "DBG_MODULE_ID_BUTTONMGR_LOG",
+ "DBG_MODULE_ID_CODECMGR_LOG",
+ "DBG_MODULE_ID_CTRLMGR_LOG",
+ "DBG_MODULE_ID_DMAMGR_LOG",
+ "DBG_MODULE_ID_EVTMGR_LOG",
+ "DBG_MODULE_ID_FLASHMGR_LOG",
+ "DBG_MODULE_ID_LEDMGR_LOG",
+ "DBG_MODULE_ID_POWERMGR_LOG",
+ "DBG_MODULE_ID_STREAMMGR_LOG",
+ "DBG_MODULE_ID_SENSORMGR_LOG",
+ "DBG_MODULE_ID_TUNNELMGR_LOG",
+ "DBG_MODULE_ID_USBMGR_LOG",
+ "DBG_MODULE_ID_PLUGINMGR_LOG",
+ "DBG_MODULE_ID_PLUGINVM_LOG",
+ "DBG_MODULE_ID_PACKAGEUTILS_LOG",
+ "DBG_MODULE_ID_ENDPOINT_LOG",
+ "DBG_MODULE_ID_PUTMSG_LOG",
+ "DBG_MODULE_ID_CONTROLLER_LOG",
+ "DBG_MODULE_ID_MIPSPROFILER_LOG",
+ "DBG_MODULE_ID_DEBUGMONITOR_LOG",
+ "DBG_MODULE_ID_SSPDRV_LOG",
+ "DBG_MODULE_ID_AFDRV_LOG",
+ "DBG_MODULE_ID_SPIDRV_LOG",
+ "DBG_MODULE_ID_I2CDRV_LOG",
+ "DBG_MODULE_ID_A400DRV_LOG",
+ "DBG_MODULE_ID_ADAU1361DRV_LOG",
+ "DBG_MODULE_ID_MAX98090DRV_LOG",
+ "DBG_MODULE_ID_BQ27425DRV_LOG",
+ "DBG_MODULE_ID_USBDRV_LOG",
+ "DBG_MODULE_ID_CSR8811_LOG",
+ "DBG_MODULE_ID_CYW20707DRV_LOG",
+ "DBG_MODULE_ID_BUTTONDRV_LOG",
+ "DBG_MODULE_ID_LEDDRV_LOG",
+ "DBG_MODULE_ID_TIMERDRV_LOG",
+ "DBG_MODULE_ID_UARTDRV_LOG",
+ "DBG_MODULE_ID_FLASHDRV_LOG",
+ "DBG_MODULE_ID_DMADRV_LOG",
+ "DBG_MODULE_ID_GPIODRV_LOG",
+ "DBG_MODULE_ID_MACDRV_LOG",
+ "DBG_MODULE_ID_STMRDRV_LOG",
+ "DBG_MODULE_ID_STMRPTDRV_LOG",
+ "DBG_MODULE_ID_SLIMBUSDRV_LOG",
+ "DBG_MODULE_ID_SSENSORDRV_LOG",
+ "DBG_MODULE_ID_STRMDRV_LOG",
+ "DBG_MODULE_ID_CPUSTRMDRV_LOG",
+ "DBG_MODULE_ID_CLKTREEUTILS_LOG",
+ "DBG_MODULE_ID_SCRIPTMGR_LOG",
+ "DBG_MODULE_ID_MODULES_LOG",
+ "DBG_MODULE_ID_ROUTESMGR_LOG",
+ "DBG_MODULE_ID_RTELEMCYPRESSAUDIO_LOG",
+ "DBG_MODULE_ID_RTELEMDAURAHEADSET_LOG",
+ "DBG_MODULE_ID_RTELEMESTRELLABTAUDIO_LOG",
+ "DBG_MODULE_ID_RTELEMESTRELLACODEC_LOG",
+ "DBG_MODULE_ID_RTELEMESTRELLAUSB_LOG",
+ "DBG_MODULE_ID_RTELEMPDM_LOG",
+ "DBG_MODULE_ID_RTELEMPLUGIN_LOG",
+ "DBG_MODULE_ID_RTELEMFILE_LOG",
+ "DBG_MODULE_ID_TASK_LOG",
+ "DBG_MODULE_ID_BTCORE_LOG",
+ "DBG_MODULE_ID_BTA2DP_LOG",
+ "DBG_MODULE_ID_PERFMON_LOG",
+ "DBG_MODULE_ID_TRACELOG_LOG",
+ "DBG_MODULE_ID_HEAPCOMPACTOR_LOG",
+ "DBG_MODULE_ID_RESOURCEHANDLER_LOG",
+ "DBG_MODULE_ID_LOWPOWERSTREAMMGR_LOG",
+ "DBG_MODULE_ID_SSPSTREAMMGR_LOG",
+ "DBG_MODULE_ID_TUNNELSTREAMMGR_LOG",
+ "DBG_MODULE_ID_TEMPLATE_LOG",
+ "DBG_MODULE_ID_TEMPLATEMODULE_LOG",
+ "DBG_MODULE_ID_FILTER_LOG",
+ "DBG_MODULE_ID_I2SDRV_LOG",
+ "DBG_MODULE_ID_PCMDRV_LOG",
+ "DBG_MODULE_ID_PDMDRV_LOG",
+ "DBG_MODULE_ID_REGMAPDRV_LOG",
+ "DBG_MODULE_ID_SPIREGMAP_LOG",
+ "DBG_MODULE_ID_STMRTIMER_LOG",
+ "DBG_MODULE_ID_RTOSOPS_LOG",
+ "DBG_MODULE_ID_MEMORYMGR_LOG",
+ "DBG_MODULE_ID_ICPUDRV_LOG",
+ "DBG_MODULE_ID_FRAMEMGR_LOG",
+ "DBG_MODULE_ID_DEBUGPRINT_LOG",
+ "DBG_MODULE_ID_DATABASE_LOG",
+ "DBG_MODULE_ID_BULKTRANSFER_LOG",
+ "DBG_MODULE_ID_ROMECONTROLPORT_LOG",
+ "DBG_MODULE_ID_NOTIFYSERVICE_LOG",
+ "DBG_MODULE_ID_SYSTEMSERVICE_LOG",
+ "DBG_MODULE_ID_UISERVICE_LOG",
+ "DBG_MODULE_ID_USBSERVICE_LOG",
+ "DBG_MODULE_ID_USBCONTROLLER_LOG",
+ "DBG_MODULE_ID_BTCONTROLLER_LOG",
+ "DBG_MODULE_ID_LIGHTHOUSEAPP_LOG",
+ "DBG_MODULE_ID_I2CMASTER_LOG",
+ "DBG_MODULE_ID_I2CSLAVE_LOG",
+ "DBG_MODULE_ID_PLATFORM_LOG",
+ "DBG_MODULE_ID_TRCKERNELPORT_LOG",
+ "DBG_MODULE_ID_HWINTERFACE_LOG",
+ "DBG_MODULE_ID_FLICKERSENSORDRV_LOG",
+ "DBG_MODULE_ID_TIEQ_SSAMPLE_STRM_DRV_LOG",
+ "DBG_MODULE_ID_SBL",
+ "DBG_MODULE_ID_FORCE_SIZE" };
+
+enum debug_level_e
+{
+ DBG_LOG_LVL_OFF = 0,
+ DBG_LOG_LVL_CUSTOM,
+ DBG_LOG_LVL_FATAL,
+ DBG_LOG_LVL_ERROR,
+ DBG_LOG_LVL_WARN,
+ DBG_LOG_LVL_INFO,
+ DBG_LOG_LVL_DEBUG,
+ DBG_LOG_LVL_TRACE,
+
+ DBG_LOG_LVL_NUM,
+ /* Force enums to be of size int */
+ DBG_LOG_LVL_FORCE_SIZE = INT_MAX
+};
+
+/* See ${KERNEL}/include/linux/mfd/adnc/iaxxx-core.h */
+enum file_name
+{
+ CM4_DUMP_DEBUG = 0,
+ HMD_DUMP_DEBUG = 1,
+ DMX_DUMP_DEBUG = 2,
+ CM4_DUMP_CRASH = 3,
+ HMD_DUMP_CRASH = 4,
+ DMX_DUMP_CRASH = 5,
+ FILE_MAX = 6
+};
+
+enum hmd_dmx_index
+{
+ START_HMD_DMX_INDEX = 0,
+ EXCEPTION_INDEX = 1,
+ EPC1_INDEX = 2,
+ HMD_DMX_INDEX_MAX = 3,
+};
+
+enum cm4_index
+{
+ START_CM4_INDEX = 0,
+ FAULT_STATUS_INDEX = 6,
+ CM4_INDEX_MAX = 7,
+};
+#endif
diff --git a/tests/crash_event_logger.c b/tests/crash_event_logger.c
index 16b7553..1f74c9b 100755
--- a/tests/crash_event_logger.c
+++ b/tests/crash_event_logger.c
@@ -29,6 +29,7 @@
#define LOG_TAG "ia_crash_event_logger"
#include <cutils/log.h>
#include <cutils/uevent.h>
+#include "crash_analyzer.h"
#define UEVENT_MSG_LEN (1024)
#define BUF_SIZE (4096)
@@ -36,10 +37,13 @@
#define REGDUMP_LOGGER_DEV "/dev/regdump"
#define CRASH_DUMP_FILE_PREFIX "/data/data/dump_crash_"
#define REG_ACCESS_FILE_PREFIX "/data/data/dump_reg_access_history_"
+#define CRASH_REASON_FILE_PREFIX "/data/data/dump_crash_reason_"
+#define SSR_CRASH_REASON_PREFIX "ia_dump_crash_reason_"
#define BIN_EXTN ".bin"
#define TXT_EXTN ".txt"
#define MAX_FILENAME_LEN 512
#define MAX_TIMESTR_LEN 64
+#define CRASH_DUMP_ANALYZER_MAX_STR_LEN 512
#define SSR_RAMDUMP_PREFIX "ramdump_audio_codec_"
#define SSR_CRASH_FILE_PREFIX "ia_crash_dump_"
@@ -64,6 +68,7 @@ char *crash_dump_split_file_names[] =
"/data/data/dump_crash_SSP_RAM0_",
"/data/data/dump_crash_SSP_RAM1_",
"/data/data/dump_crash_SSP_ROM0_",
+ CRASH_REASON_FILE_PREFIX
};
char *ssr_crash_dump_split_file_names[] = {
@@ -76,41 +81,114 @@ char *ssr_crash_dump_split_file_names[] = {
"ia_dump_crash_SSP_RAM0_",
"ia_dump_crash_SSP_RAM1_",
"ia_dump_crash_SSP_ROM0_",
+ SSR_CRASH_REASON_PREFIX
};
-int split_bin(unsigned char *buf, int len, const char* time_stamp)
+void dump_crash_reason(const unsigned char *crash_dump_buf,
+ const int crash_dump_len,
+ const unsigned char *crash_reason_buf,
+ const int crash_reason_len,
+ const char *time_stamp, bool is_ssr)
{
- unsigned int header, size, tot_len, flen;
+
+ FILE *out_fp = NULL;
+ char file_name[MAX_FILENAME_LEN] = {0};
+ char crash_dump_analyzer_str[CRASH_DUMP_ANALYZER_MAX_STR_LEN] = {0};
+ int len = 0;
+ const char *crash_dump_title = " crash_analysis:";
+
+ if (is_ssr) {
+ snprintf(file_name, MAX_FILENAME_LEN, "%s%s%s%s%s",
+ SSR_DUMP_PATH, SSR_RAMDUMP_PREFIX,
+ SSR_CRASH_REASON_PREFIX,
+ time_stamp, BIN_EXTN);
+ } else {
+ snprintf(file_name, MAX_FILENAME_LEN, "%s%s%s",
+ CRASH_REASON_FILE_PREFIX, time_stamp,
+ TXT_EXTN);
+ }
+
+ out_fp = fopen(file_name, "w");
+ if (out_fp == NULL) {
+ ALOGE("Failed to open %s for writting", file_name);
+ goto exit;
+ }
+
+ len = strnlen((const char *)crash_reason_buf, crash_reason_len);
+
+ if (fwrite(crash_reason_buf, 1, len, out_fp) != len) {
+ ALOGE("%s: ERROR writing to CRASH REASON FILE", __func__);
+ goto exit;
+ }
+
+ len = analyse_crash_info(
+ crash_dump_buf, crash_dump_len, crash_dump_analyzer_str,
+ CRASH_DUMP_ANALYZER_MAX_STR_LEN);
+ if (len > 0) {
+ fwrite(crash_dump_title, 1, strlen(crash_dump_title), out_fp);
+ fwrite(crash_dump_analyzer_str, 1,
+ strlen(crash_dump_analyzer_str), out_fp);
+ }
+ ALOGI("Crash logs saved to %s", file_name);
+exit:
+ if (out_fp != NULL) {
+ fclose(out_fp);
+ }
+
+}
+
+int split_crash_dump_buffer(unsigned char *buf, const int len,
+ const char* time_stamp)
+{
+
+ unsigned int file_index = 0, size = 0, tot_len = 0, flen = 0;
int fcount = 0;
- unsigned char *ptr;
- FILE *fp;
- char file_name[MAX_FILENAME_LEN];
- int no_crashdump_files = sizeof(crash_dump_split_file_names) /
+ unsigned char *ptr = NULL;
+ FILE *fp = NULL;
+ char file_name[MAX_FILENAME_LEN] = {0};
+ int number_crashdump_files = sizeof(crash_dump_split_file_names) /
sizeof(crash_dump_split_file_names[0]);
- tot_len = 0;
- while ((tot_len < len) && (fcount++ < no_crashdump_files))
- {
- header = buf[tot_len] ;
+ if (buf == NULL || time_stamp == NULL || len <= 0) {
+ ALOGE("%s: Bad parameters", __func__);
+ return -1;
+ }
- size = buf[tot_len+8] |
- buf[tot_len+9] << 8 |
- buf[tot_len+10] << 16 |
- buf[tot_len+11] << 24 ;
+ while ((tot_len + STEP_LENGTH - 1 < len) &&
+ (fcount++ < number_crashdump_files)) {
+ file_index = buf[tot_len];
- tot_len += 12;
+ size = buf[tot_len + 8] |
+ buf[tot_len + 9] << 8 |
+ buf[tot_len + 10] << 16 |
+ buf[tot_len + 11] << 24;
- strcpy(file_name, crash_dump_split_file_names[header & 0xf]);
- strcat(file_name, time_stamp);
- strcat(file_name, BIN_EXTN);
+ tot_len += STEP_LENGTH;
- fp = fopen (file_name, "w+");
+ if (file_index >= number_crashdump_files || size > len - tot_len) {
+ continue;
+ }
- ptr = buf + tot_len;
- flen = fwrite(ptr , 1, size, fp);
- tot_len += size;
- fclose(fp);
- ALOGI("Crash logs saved to %s", file_name);
+ /* Some special handling is needed for crash reason file */
+ if (!strcmp(crash_dump_split_file_names[file_index],
+ CRASH_REASON_FILE_PREFIX)) {
+ dump_crash_reason(buf, len, buf + tot_len, size, time_stamp,
+ false);
+ }
+ else {
+ snprintf(file_name, MAX_FILENAME_LEN, "%s%s%s",
+ crash_dump_split_file_names[file_index],
+ time_stamp, BIN_EXTN);
+
+ fp = fopen(file_name, "w+");
+
+ ptr = buf + tot_len;
+
+ flen = fwrite(ptr , 1, size, fp);
+ tot_len += size;
+ fclose(fp);
+ ALOGI("Crash logs saved to %s", file_name);
+ }
}
return 0;
}
@@ -148,7 +226,7 @@ int split_crash_dump_file (const char* crash_dump_filename,
ret = -1;
goto exit;
}
- ret = split_bin(buf, len, time_stamp);
+ ret = split_crash_dump_buffer(buf, len, time_stamp);
exit:
if (fp)
@@ -285,27 +363,45 @@ exit:
/* --- functions for SSR detector ---*/
int ssr_split_bin(unsigned char *buf, int len, const char* time_stamp) {
- unsigned int header = 0, size = 0, tot_len = 0, flen = 0;
+ unsigned int file_index = 0, size = 0, tot_len = 0, flen = 0;
unsigned char *ptr = NULL;
- char file_name[MAX_FILENAME_LEN];
+ char file_name[MAX_FILENAME_LEN] = {0};
FILE *fp = NULL;
int fcount = 0;
- int no_crashdump_files = sizeof(ssr_crash_dump_split_file_names) /
+ int number_crashdump_files = sizeof(ssr_crash_dump_split_file_names) /
sizeof(ssr_crash_dump_split_file_names[0]);
- while ((tot_len < len) && (fcount++ < no_crashdump_files)) {
- header = buf[tot_len];
+ if (buf == NULL || time_stamp == NULL || len <= 0) {
+ ALOGE("%s: Bad parameters", __func__);
+ return -1;
+ }
+
+ while ((tot_len + STEP_LENGTH - 1 < len) &&
+ (fcount++ < number_crashdump_files)) {
+
+ file_index = buf[tot_len];
size = buf[tot_len + 8] |
buf[tot_len + 9] << 8 |
buf[tot_len + 10] << 16 |
buf[tot_len + 11] << 24 ;
- tot_len += 12;
+ tot_len += STEP_LENGTH;
+
+ if (file_index >= number_crashdump_files || size > len - tot_len) {
+ continue;
+ }
+
+ /* Some special handling is needed for crash reason file */
+ if (!strcmp(ssr_crash_dump_split_file_names[file_index],
+ SSR_CRASH_REASON_PREFIX)) {
+ dump_crash_reason(buf, len, buf + tot_len, size, time_stamp, true);
+ continue;
+ }
snprintf(file_name, MAX_FILENAME_LEN, "%s%s%s%s%s",
SSR_DUMP_PATH, SSR_RAMDUMP_PREFIX,
- ssr_crash_dump_split_file_names[header & 0xf],
+ ssr_crash_dump_split_file_names[file_index],
time_stamp, BIN_EXTN);
fp = fopen(file_name, "w+");
@@ -416,13 +512,42 @@ exit:
return;
}
+void check_crash_reason_file(const char *time_stamp)
+{
+ FILE *out_fp = NULL;
+ char file_name[MAX_FILENAME_LEN] = {0};
+ const char *default_crash_reason = "Iaxxx Firmware Crashed";
+
+ snprintf(file_name, MAX_FILENAME_LEN, "%s%s%s%s%s",
+ SSR_DUMP_PATH, SSR_RAMDUMP_PREFIX,
+ SSR_CRASH_REASON_PREFIX,
+ time_stamp, BIN_EXTN);
+
+ if (access(file_name, F_OK) == -1) {
+ ALOGE("Write default crash reason into the crash reason file");
+
+ out_fp = fopen(file_name, "w");
+
+ if (out_fp == NULL) {
+ ALOGE("%s: Failed to open: %s , errno: %s", __func__,
+ file_name, strerror(errno));
+ return;
+ }
+
+ fwrite(default_crash_reason, 1,
+ strlen(default_crash_reason), out_fp);
+
+ fclose(out_fp);
+ }
+}
+
void ssr_dump_log() {
time_t t;
- struct tm *tm;
- char curr_time_for_property[MAX_TIMESTR_LEN];
- char curr_time_for_dump[MAX_TIMESTR_LEN];
- char out_crash_file_name[MAX_FILENAME_LEN];
- char out_reg_file_name[MAX_FILENAME_LEN];
+ struct tm *tm = NULL;
+ char curr_time_for_property[MAX_TIMESTR_LEN] = {0};
+ char curr_time_for_dump[MAX_TIMESTR_LEN] = {0};
+ char out_crash_file_name[MAX_FILENAME_LEN] = {0};
+ char out_reg_file_name[MAX_FILENAME_LEN] = {0};
// get current time
t = time(NULL);
@@ -455,6 +580,9 @@ void ssr_dump_log() {
curr_time_for_dump, TXT_EXTN);
ssr_copy_log(REGDUMP_LOGGER_DEV, out_reg_file_name);
ALOGI("Register access history has been dumped %s", out_reg_file_name);
+
+ // Check the crash reason file
+ check_crash_reason_file(curr_time_for_dump);
}
/* --- main function --- */