From: Mika Isojärvi Date: Thu, 23 Apr 2015 22:33:28 +0000 (-0700) Subject: Log backtrace on crash on linux. X-Git-Tag: upstream/0.1.0~1386 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=83a2de97c5c5ed52df9eb445919f09c950b8c846;p=platform%2Fupstream%2FVK-GL-CTS.git Log backtrace on crash on linux. Change-Id: I04933873c5a637bc0a414200e391b30b20b2c036 --- diff --git a/framework/qphelper/qpCrashHandler.c b/framework/qphelper/qpCrashHandler.c index f78c0c7..792ae37 100644 --- a/framework/qphelper/qpCrashHandler.c +++ b/framework/qphelper/qpCrashHandler.c @@ -31,6 +31,14 @@ #include #include +#include + +#if DE_OS == DE_OS_UNIX +# include +# include +# include +# include +#endif #if 0 # define DBGPRINT(X) qpPrintf X @@ -510,9 +518,115 @@ void qpCrashHandler_destroy (qpCrashHandler* handler) deFree(handler); } +#if (DE_PTR_SIZE == 8) +# define PTR_FMT "0x%016" +#elif (DE_PTR_SIZE == 4) +# define PTR_FMT "0x%08" +#else +# error Unknwon DE_PTR_SIZE +#endif + void qpCrashHandler_writeCrashInfo (qpCrashHandler* crashHandler, qpWriteCrashInfoFunc writeInfo, void* userPtr) { qpCrashInfo_write(&crashHandler->crashInfo, writeInfo, userPtr); + +#if (DE_OS == DE_OS_UNIX) + { + char tmpFileName[] = "backtrace-XXXXXX"; + int tmpFile = mkstemp(tmpFileName); + + if (tmpFile == -1) + { + writeInfoFormat(writeInfo, userPtr, "Failed to create tmpfile '%s' for the backtrace %s.", tmpFileName, strerror(errno)); + return; + } + else + { + void* symbols[32]; + int symbolCount; + int symbolNdx; + + /* Remove file from filesystem. */ + remove(tmpFileName); + + symbolCount = backtrace(symbols, DE_LENGTH_OF_ARRAY(symbols)); + backtrace_symbols_fd(symbols, symbolCount, tmpFile); + + if (lseek(tmpFile, 0, SEEK_SET) < 0) + { + writeInfoFormat(writeInfo, userPtr, "Failed to seek to the beginning of the trace file %s.", strerror(errno)); + close(tmpFile); + return; + } + + for (symbolNdx = 0; symbolNdx < symbolCount; symbolNdx++) + { + char nameBuffer[256]; + size_t symbolNameLength = 0; + char c; + + { + const int ret = snprintf(nameBuffer, DE_LENGTH_OF_ARRAY(nameBuffer), PTR_FMT PRIXPTR " : ", (uintptr_t)symbols[symbolNdx]); + + if (ret < 0) + { + writeInfoFormat(writeInfo, userPtr, "Failed to print symbol pointer."); + symbolNameLength = 0; + } + else if (ret >= DE_LENGTH_OF_ARRAY(nameBuffer)) + { + symbolNameLength = DE_LENGTH_OF_ARRAY(nameBuffer) - 1; + nameBuffer[DE_LENGTH_OF_ARRAY(nameBuffer) - 1] = '\0'; + } + else + symbolNameLength = ret; + } + + for (;;) + { + if (read(tmpFile, &c, 1) == 1) + { + if (c == '\n') + { + /* Flush nameBuffer and move to next symbol. */ + nameBuffer[symbolNameLength] = '\0'; + writeInfo(userPtr, nameBuffer); + break; + } + else + { + /* Add character to buffer if there is still space left. */ + if (symbolNameLength+1 < DE_LENGTH_OF_ARRAY(nameBuffer)) + { + nameBuffer[symbolNameLength] = c; + symbolNameLength++; + } + } + } + else + { + /* Flush nameBuffer. */ + nameBuffer[symbolNameLength] = '\0'; + writeInfo(userPtr, nameBuffer); + + /* Temp file ended unexpectedly? */ + writeInfoFormat(writeInfo, userPtr, "Unexpected EOF reading backtrace file '%s'", tmpFileName); + close(tmpFile); + tmpFile = -1; + + break; + } + } + + if (tmpFile == -1) + break; + } + + if (tmpFile != -1) + close(tmpFile); + } + } +#endif } #endif /* generic */