diff options
author | Shanmugam Vasudevan <Shanmugam.Vasudevan@knowles.com> | 2019-06-24 18:55:24 -0700 |
---|---|---|
committer | Juyu Chen <juyuchen@google.com> | 2019-07-18 10:26:02 -0700 |
commit | 459085d8328af6b650a9726e84e8105484a7851e (patch) | |
tree | 7dd96115f89ad0d6a58a8d17ddaa81bd3b61a1e4 | |
parent | d99ddd71f5b3ab9e0b6ced7ffbf42f7a3e186a8b (diff) | |
download | android_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.mk | 2 | ||||
-rw-r--r-- | tests/crash_analyzer.c | 252 | ||||
-rw-r--r-- | tests/crash_analyzer.h | 10 | ||||
-rw-r--r-- | tests/crash_analyzer_defs.h | 228 | ||||
-rwxr-xr-x | tests/crash_event_logger.c | 202 |
5 files changed, 656 insertions, 38 deletions
@@ -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 --- */ |