mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 23:57:47 +00:00
[posix] add backtrace support (#8358)
This commit logs the backtrace when the Thread crashes on the Linux and Android.
This commit is contained in:
+3
-1
@@ -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 \
|
||||
|
||||
@@ -80,6 +80,7 @@ UPTIME ?= 1
|
||||
|
||||
COMMONCFLAGS := \
|
||||
-g \
|
||||
-rdynamic \
|
||||
$(NULL)
|
||||
|
||||
# If the user has asserted COVERAGE, alter the configuration options
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -46,6 +46,7 @@ libopenthread_posix_a_CPPFLAGS = \
|
||||
libopenthread_posix_a_SOURCES = \
|
||||
alarm.cpp \
|
||||
backbone.cpp \
|
||||
backtrace.cpp \
|
||||
daemon.cpp \
|
||||
entropy.cpp \
|
||||
firewall.cpp \
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -524,6 +524,12 @@ extern unsigned int gBackboneNetifIndex;
|
||||
*/
|
||||
bool platformInfraIfIsRunning(void);
|
||||
|
||||
/**
|
||||
* This function initializes backtrace module.
|
||||
*
|
||||
*/
|
||||
void platformBacktraceInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user