[posix] add backtrace support (#8358)

This commit logs the backtrace when the Thread crashes on the Linux
and Android.
This commit is contained in:
Zhanglong Xia
2022-11-04 08:48:03 -07:00
committed by GitHub
parent df20f3d91a
commit d92520c3e2
8 changed files with 207 additions and 1 deletions
+3 -1
View File
@@ -385,6 +385,7 @@ LOCAL_SRC_FILES := \
src/lib/url/url.cpp \
src/posix/platform/alarm.cpp \
src/posix/platform/backbone.cpp \
src/posix/platform/backtrace.cpp \
src/posix/platform/daemon.cpp \
src/posix/platform/entropy.cpp \
src/posix/platform/firewall.cpp \
@@ -615,7 +616,8 @@ LOCAL_CPPFLAGS := \
LOCAL_LDLIBS := \
-lanl \
-lrt \
-lutil
-lutil \
-rdynamic \
LOCAL_SRC_FILES := \
src/posix/cli_readline.cpp \
+1
View File
@@ -80,6 +80,7 @@ UPTIME ?= 1
COMMONCFLAGS := \
-g \
-rdynamic \
$(NULL)
# If the user has asserted COVERAGE, alter the configuration options
+3
View File
@@ -98,9 +98,12 @@ endif()
set(OT_POSIX_CONFIG_RCP_VENDOR_INTERFACE "vendor_interface_example.cpp"
CACHE STRING "vendor interface implementation")
set(CMAKE_EXE_LINKER_FLAGS "-rdynamic ${CMAKE_EXE_LINKER_FLAGS}" PARENT_SCOPE)
add_library(openthread-posix
alarm.cpp
backbone.cpp
backtrace.cpp
daemon.cpp
entropy.cpp
firewall.cpp
+1
View File
@@ -46,6 +46,7 @@ libopenthread_posix_a_CPPFLAGS = \
libopenthread_posix_a_SOURCES = \
alarm.cpp \
backbone.cpp \
backtrace.cpp \
daemon.cpp \
entropy.cpp \
firewall.cpp \
+170
View File
@@ -0,0 +1,170 @@
/*
* Copyright (c) 2022, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements backtrace for posix.
*/
#include "openthread-posix-config.h"
#include "platform-posix.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "common/code_utils.hpp"
#include "common/logging.hpp"
#if OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE
#if defined(__linux__) && !OPENTHREAD_ENABLE_ANDROID_NDK
#if OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE
#include <log/log.h>
#include <utils/CallStack.h>
#include <utils/Printer.h>
class LogPrinter : public android::Printer
{
public:
virtual void printLine(const char *string) { otLogCritPlat("%s", string); }
};
static void dumpStack(void)
{
LogPrinter printer;
android::CallStack callstack;
callstack.update();
callstack.print(printer);
}
#else // OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE
#include <cxxabi.h>
#include <execinfo.h>
static void demangleSymbol(int aIndex, const char *aSymbol)
{
constexpr uint16_t kMaxNameSize = 256;
int status;
char program[kMaxNameSize + 1];
char mangledName[kMaxNameSize + 1];
char * demangledName = nullptr;
char * functionName = nullptr;
unsigned int offset = 0;
unsigned int address = 0;
// Try to demangle a C++ name
if (sscanf(aSymbol, "%256[^(]%*[^_]%256[^)+]%*[^0x]%x%*[^0x]%x", program, mangledName, &offset, &address) == 4)
{
demangledName = abi::__cxa_demangle(mangledName, nullptr, nullptr, &status);
functionName = demangledName;
}
VerifyOrExit(demangledName == nullptr);
// If failed to demangle a C++ name, try to get a regular C symbol
if (sscanf(aSymbol, "%256[^(](%256[^)+]%*[^0x]%x%*[^0x]%x", program, mangledName, &offset, &address) == 4)
{
functionName = mangledName;
}
exit:
if (functionName != nullptr)
{
otLogCritPlat("#%2d: %s %s+0x%x [0x%x]\n", aIndex, program, functionName, offset, address);
}
else
{
otLogCritPlat("#%2d: %s\n", aIndex, aSymbol);
}
if (demangledName != nullptr)
{
free(demangledName);
}
}
static void dumpStack(void)
{
constexpr uint8_t kMaxDepth = 50;
void * stack[kMaxDepth];
char ** symbols;
int depth;
depth = backtrace(stack, kMaxDepth);
symbols = backtrace_symbols(stack, depth);
VerifyOrExit(symbols != nullptr);
for (int i = 0; i < depth; i++)
{
demangleSymbol(i, symbols[i]);
}
free(symbols);
exit:
return;
}
#endif // OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE
static void signalCritical(int sig, siginfo_t *info, void *ucontext)
{
OT_UNUSED_VARIABLE(ucontext);
OT_UNUSED_VARIABLE(info);
otLogCritPlat("------------------ BEGINNING OF CRASH -------------");
otLogCritPlat("*** FATAL ERROR: Caught signal: %d (%s)", sig, strsignal(sig));
dumpStack();
otLogCritPlat("------------------ END OF CRASH ------------------");
exit(EXIT_FAILURE);
}
void platformBacktraceInit(void)
{
struct sigaction sigact;
sigact.sa_sigaction = &signalCritical;
sigact.sa_flags = SA_RESTART | SA_SIGINFO | SA_NOCLDWAIT;
sigaction(SIGABRT, &sigact, (struct sigaction *)nullptr);
sigaction(SIGILL, &sigact, (struct sigaction *)nullptr);
sigaction(SIGSEGV, &sigact, (struct sigaction *)nullptr);
sigaction(SIGBUS, &sigact, (struct sigaction *)nullptr);
sigaction(SIGTRAP, &sigact, (struct sigaction *)nullptr);
sigaction(SIGFPE, &sigact, (struct sigaction *)nullptr);
}
#else // defined(__linux__) && !OPENTHREAD_ENABLE_ANDROID_NDK
void platformBacktraceInit(void)
{
}
#endif // defined(__linux__) && !OPENTHREAD_ENABLE_ANDROID_NDK
#endif // OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE
@@ -304,4 +304,23 @@
#define OPENTHREAD_POSIX_CONFIG_NAT64_CIDR "192.168.255.0/24"
#endif
/**
* @def OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE
*
* Define as 1 to enable backtrace support.
*
*/
#ifndef OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE
#define OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE 1
#endif
/**
* @def OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE
*
* Define as 1 to enable android support.
*
*/
#ifndef OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE
#define OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE 0
#endif
#endif // OPENTHREAD_PLATFORM_CONFIG_H_
+6
View File
@@ -524,6 +524,12 @@ extern unsigned int gBackboneNetifIndex;
*/
bool platformInfraIfIsRunning(void);
/**
* This function initializes backtrace module.
*
*/
void platformBacktraceInit(void);
#ifdef __cplusplus
}
#endif
+4
View File
@@ -123,6 +123,10 @@ static const char *getTrelRadioUrl(otPlatformConfig *aPlatformConfig)
void platformInit(otPlatformConfig *aPlatformConfig)
{
#if OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE
platformBacktraceInit();
#endif
platformAlarmInit(aPlatformConfig->mSpeedUpFactor, aPlatformConfig->mRealTimeSignal);
platformRadioInit(get802154RadioUrl(aPlatformConfig));