[lldb] Call os_log_fault on lldb_assert

Call `os_log_fault` when an lldb assert fails. We piggyback off
`LLVM_SUPPORT_XCODE_SIGNPOSTS`, which also depends on `os_log`, to avoid
having to introduce another CMake check and corresponding define.

This patch also adds a small test using lldb-test that verifies we abort
with a "regular" assertion when asserts are enabled.

Differential revision: https://reviews.llvm.org/D98987
This commit is contained in:
Jonas Devlieghere 2021-03-19 14:20:26 -07:00
parent 0de3d1c814
commit e089b5e9e1
4 changed files with 30 additions and 2 deletions

View file

@ -20,6 +20,6 @@
namespace lldb_private {
void lldb_assert(bool expression, const char *expr_text, const char *func,
const char *file, unsigned int line);
}
} // namespace lldb_private
#endif // LLDB_UTILITY_LLDBASSERT_H

View file

@ -7,11 +7,15 @@
//===----------------------------------------------------------------------===//
#include "lldb/Utility/LLDBAssert.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
#include <os/log.h>
#endif
using namespace llvm;
using namespace lldb_private;
@ -24,6 +28,14 @@ void lldb_private::lldb_assert(bool expression, const char *expr_text,
// If asserts are enabled abort here.
assert(false && "lldb_assert failed");
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
if (__builtin_available(macos 10.12, iOS 10, tvOS 10, watchOS 3, *)) {
os_log_fault(OS_LOG_DEFAULT,
"Assertion failed: (%s), function %s, file %s, line %u\n",
expr_text, func, file, line);
}
#endif
// In a release configuration it will print a warning and encourage the user
// to file a bug report, similar to LLVMs crash handler, and then return
// execution.

View file

@ -0,0 +1,4 @@
# REQUIRES: asserts
# RUN: not --crash lldb-test assert > %t.error 2>&1
# RUN: cat %t.error | FileCheck %s
# CHECK: Assertion failed: (false && "lldb_assert failed")

View file

@ -29,6 +29,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
@ -57,6 +58,7 @@ cl::SubCommand ObjectFileSubcommand("object-file",
"Display LLDB object file information");
cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
cl::SubCommand AssertSubcommand("assert", "Test assert handling");
cl::opt<std::string> Log("log", cl::desc("Path to a log file"), cl::init(""),
cl::sub(BreakpointSubcommand),
@ -236,6 +238,9 @@ bool evalFree(StringRef Line, IRMemoryMapTestState &State);
int evaluateMemoryMapCommands(Debugger &Dbg);
} // namespace irmemorymap
namespace assert {
int lldb_assert(Debugger &Dbg);
} // namespace assert
} // namespace opts
std::vector<CompilerContext> parseCompilerContext() {
@ -1077,6 +1082,11 @@ int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) {
return 0;
}
int opts::assert::lldb_assert(Debugger &Dbg) {
lldbassert(false && "lldb-test assert");
return 1;
}
int main(int argc, const char *argv[]) {
StringRef ToolName = argv[0];
sys::PrintStackTraceOnErrorSignal(ToolName);
@ -1120,6 +1130,8 @@ int main(int argc, const char *argv[]) {
return opts::symbols::dumpSymbols(*Dbg);
if (opts::IRMemoryMapSubcommand)
return opts::irmemorymap::evaluateMemoryMapCommands(*Dbg);
if (opts::AssertSubcommand)
return opts::assert::lldb_assert(*Dbg);
WithColor::error() << "No command specified.\n";
return 1;