Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lldb/include/lldb/Target/StackFrameRecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ class ScriptedStackFrameRecognizer : public StackFrameRecognizer {
class StackFrameRecognizerManager {
public:
static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
ConstString module,
ConstString symbol,
ConstString module, ConstString symbol,
ConstString alternate_symbol,
bool first_instruction_only = true);

static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
Expand All @@ -113,7 +113,8 @@ class StackFrameRecognizerManager {
static void ForEach(
std::function<void(uint32_t recognizer_id, std::string recognizer_name,
std::string module, std::string symbol,
bool regexp)> const &callback);
std::string alternate_symbol, bool regexp)> const
&callback);

static bool RemoveRecognizerWithID(uint32_t recognizer_id);

Expand Down
9 changes: 5 additions & 4 deletions lldb/source/Commands/CommandObjectFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command,
} else {
auto module = ConstString(m_options.m_module);
auto func = ConstString(m_options.m_function);
StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func);
StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func, {});
}
#endif

Expand Down Expand Up @@ -961,12 +961,13 @@ class CommandObjectFrameRecognizerList : public CommandObjectParsed {
StackFrameRecognizerManager::ForEach(
[&result, &any_printed](uint32_t recognizer_id, std::string name,
std::string function, std::string symbol,
bool regexp) {
std::string alternate_symbol, bool regexp) {
if (name == "")
name = "(internal)";
result.GetOutputStream().Printf(
"%d: %s, module %s, function %s%s\n", recognizer_id, name.c_str(),
function.c_str(), symbol.c_str(), regexp ? " (regexp)" : "");
"%d: %s, module %s, function %s{%s}%s\n", recognizer_id,
name.c_str(), function.c_str(), symbol.c_str(),
alternate_symbol.c_str(), regexp ? " (regexp)" : "");
any_printed = true;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2723,6 +2723,7 @@ static void RegisterObjCExceptionRecognizer() {
std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
module.GetFilename(), function, /*first_instruction_only*/ true);
module.GetFilename(), function, /*alternate_symbol*/ {},
/*first_instruction_only*/ true);
});
}
71 changes: 29 additions & 42 deletions lldb/source/Target/AssertFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,22 @@ using namespace lldb;
using namespace lldb_private;

namespace lldb_private {
/// Checkes if the module containing a symbol has debug info.
///
/// \param[in] target
/// The target containing the module.
/// \param[in] module_spec
/// The module spec that should contain the symbol.
/// \param[in] symbol_name
/// The symbol's name that should be contained in the debug info.
/// \return
/// If \b true the symbol was found, \b false otherwise.
bool ModuleHasDebugInfo(Target &target, FileSpec &module_spec,
StringRef symbol_name) {
ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);

if (!module_sp)
return false;

return module_sp->FindFirstSymbolWithNameAndType(ConstString(symbol_name));
}

/// Fetches the abort frame location depending on the current platform.
///
/// \param[in] process_sp
/// The process that is currently aborting. This will give us information on
/// the target and the platform.
/// \return
/// If the platform is supported, returns an optional tuple containing
/// the abort module as a \a FileSpec and the symbol name as a \a StringRef.
/// the abort module as a \a FileSpec and two symbol names as two \a
/// StringRef. The second \a StringRef may be empty.
/// Otherwise, returns \a llvm::None.
llvm::Optional<std::tuple<FileSpec, StringRef>>
llvm::Optional<std::tuple<FileSpec, StringRef, StringRef>>
GetAbortLocation(Process *process) {
Target &target = process->GetTarget();

FileSpec module_spec;
StringRef symbol_name;
StringRef symbol_name, alternate_symbol_name;

switch (target.GetArchitecture().GetTriple().getOS()) {
case llvm::Triple::Darwin:
Expand All @@ -60,17 +41,16 @@ GetAbortLocation(Process *process) {
break;
case llvm::Triple::Linux:
module_spec = FileSpec("libc.so.6");
symbol_name = "__GI_raise";
if (!ModuleHasDebugInfo(target, module_spec, symbol_name))
symbol_name = "raise";
symbol_name = "raise";
alternate_symbol_name = "__GI_raise";
break;
default:
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
LLDB_LOG(log, "AssertFrameRecognizer::GetAbortLocation Unsupported OS");
return llvm::None;
}

return std::make_tuple(module_spec, symbol_name);
return std::make_tuple(module_spec, symbol_name, alternate_symbol_name);
}

/// Fetches the assert frame location depending on the current platform.
Expand All @@ -80,15 +60,15 @@ GetAbortLocation(Process *process) {
/// the target and the platform.
/// \return
/// If the platform is supported, returns an optional tuple containing
/// the asserting frame module as a \a FileSpec and the symbol name as a \a
/// StringRef.
/// the asserting frame module as a \a FileSpec and two possible symbol
/// names as two \a StringRef. The second \a StringRef may be empty.
/// Otherwise, returns \a llvm::None.
llvm::Optional<std::tuple<FileSpec, StringRef>>
llvm::Optional<std::tuple<FileSpec, StringRef, StringRef>>
GetAssertLocation(Process *process) {
Target &target = process->GetTarget();

FileSpec module_spec;
StringRef symbol_name;
StringRef symbol_name, alternate_symbol_name;

switch (target.GetArchitecture().GetTriple().getOS()) {
case llvm::Triple::Darwin:
Expand All @@ -98,17 +78,16 @@ GetAssertLocation(Process *process) {
break;
case llvm::Triple::Linux:
module_spec = FileSpec("libc.so.6");
symbol_name = "__GI___assert_fail";
if (!ModuleHasDebugInfo(target, module_spec, symbol_name))
symbol_name = "__assert_fail";
symbol_name = "__assert_fail";
alternate_symbol_name = "__GI___assert_fail";
break;
default:
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
LLDB_LOG(log, "AssertFrameRecognizer::GetAssertLocation Unsupported OS");
return llvm::None;
}

return std::make_tuple(module_spec, symbol_name);
return std::make_tuple(module_spec, symbol_name, alternate_symbol_name);
}

void RegisterAssertFrameRecognizer(Process *process) {
Expand All @@ -120,12 +99,14 @@ void RegisterAssertFrameRecognizer(Process *process) {
return;

FileSpec module_spec;
StringRef function_name;
std::tie(module_spec, function_name) = *abort_location;
StringRef function_name, alternate_function_name;
std::tie(module_spec, function_name, alternate_function_name) =
*abort_location;

StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP(new AssertFrameRecognizer()),
module_spec.GetFilename(), ConstString(function_name), false);
module_spec.GetFilename(), ConstString(function_name),
ConstString(alternate_function_name), /*first_instruction_only*/ false);
});
}

Expand All @@ -142,8 +123,9 @@ AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
return RecognizedStackFrameSP();

FileSpec module_spec;
StringRef function_name;
std::tie(module_spec, function_name) = *assert_location;
StringRef function_name, alternate_function_name;
std::tie(module_spec, function_name, alternate_function_name) =
*assert_location;

const uint32_t frames_to_fetch = 5;
const uint32_t last_frame_index = frames_to_fetch - 1;
Expand All @@ -163,8 +145,13 @@ AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
SymbolContext sym_ctx =
prev_frame_sp->GetSymbolContext(eSymbolContextEverything);

if (sym_ctx.module_sp->GetFileSpec().FileEquals(module_spec) &&
sym_ctx.GetFunctionName() == ConstString(function_name)) {
if (!sym_ctx.module_sp->GetFileSpec().FileEquals(module_spec))
continue;

ConstString func_name = sym_ctx.GetFunctionName();
if (func_name == ConstString(function_name) ||
alternate_function_name.empty() ||
func_name == ConstString(alternate_function_name)) {

// We go a frame beyond the assert location because the most relevant
// frame for the user is the one in which the assert function was called.
Expand Down
45 changes: 28 additions & 17 deletions lldb/source/Target/StackFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,28 @@ ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {

class StackFrameRecognizerManagerImpl {
public:
void AddRecognizer(StackFrameRecognizerSP recognizer,
ConstString module, ConstString symbol,
void AddRecognizer(StackFrameRecognizerSP recognizer, ConstString module,
ConstString symbol, ConstString alternate_symbol,
bool first_instruction_only) {
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(),
symbol, RegularExpressionSP(),
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer,
false, module, RegularExpressionSP(), symbol,
alternate_symbol, RegularExpressionSP(),
first_instruction_only});
}

void AddRecognizer(StackFrameRecognizerSP recognizer,
RegularExpressionSP module, RegularExpressionSP symbol,
bool first_instruction_only) {
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), module,
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer,
true, ConstString(), module, ConstString(),
ConstString(), symbol, first_instruction_only});
}

void ForEach(
std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
std::string symbol, bool regexp)> const &callback) {
std::function<void(uint32_t recognized_id, std::string recognizer_name,
std::string module, std::string symbol,
std::string alternate_symbol, bool regexp)> const
&callback) {
for (auto entry : m_recognizers) {
if (entry.is_regexp) {
std::string module_name;
Expand All @@ -79,11 +83,12 @@ class StackFrameRecognizerManagerImpl {
symbol_name = entry.symbol_regexp->GetText().str();

callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
symbol_name, true);
symbol_name, {}, true);

} else {
callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(),
entry.symbol.GetCString(), false);
callback(entry.recognizer_id, entry.recognizer->GetName(),
entry.module.GetCString(), entry.symbol.GetCString(),
entry.alternate_symbol.GetCString(), false);
}
}
}
Expand Down Expand Up @@ -120,7 +125,10 @@ class StackFrameRecognizerManagerImpl {
if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue;

if (entry.symbol)
if (entry.symbol != function_name) continue;
if (entry.symbol != function_name &&
(!entry.alternate_symbol ||
entry.alternate_symbol != function_name))
continue;

if (entry.symbol_regexp)
if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
Expand Down Expand Up @@ -149,6 +157,7 @@ class StackFrameRecognizerManagerImpl {
ConstString module;
RegularExpressionSP module_regexp;
ConstString symbol;
ConstString alternate_symbol;
RegularExpressionSP symbol_regexp;
bool first_instruction_only;
};
Expand All @@ -163,10 +172,10 @@ StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() {
}

void StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP recognizer, ConstString module,
ConstString symbol, bool first_instruction_only) {
GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
first_instruction_only);
StackFrameRecognizerSP recognizer, ConstString module, ConstString symbol,
ConstString alternate_symbol, bool first_instruction_only) {
GetStackFrameRecognizerManagerImpl().AddRecognizer(
recognizer, module, symbol, alternate_symbol, first_instruction_only);
}

void StackFrameRecognizerManager::AddRecognizer(
Expand All @@ -177,8 +186,10 @@ void StackFrameRecognizerManager::AddRecognizer(
}

void StackFrameRecognizerManager::ForEach(
std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
std::string symbol, bool regexp)> const &callback) {
std::function<void(uint32_t recognized_id, std::string recognizer_name,
std::string module, std::string symbol,
std::string alternate_symbol, bool regexp)> const
&callback) {
GetStackFrameRecognizerManagerImpl().ForEach(callback);
}

Expand Down
2 changes: 1 addition & 1 deletion lldb/test/Shell/Recognizer/assert.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# UNSUPPORTED: system-windows, system-linux
# UNSUPPORTED: system-windows
# RUN: %clang_host -g -O0 %S/Inputs/assert.c -o %t.out
# RUN: %lldb -b -s %s %t.out | FileCheck %s
run
Expand Down
1 change: 1 addition & 0 deletions lldb/unittests/Target/StackFrameRecognizerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ TEST_F(StackFrameRecognizerTest, NullModuleRegex) {
StackFrameRecognizerManager::ForEach(
[&any_printed](uint32_t recognizer_id, std::string name,
std::string function, std::string symbol,
std::string alternate_symbol,
bool regexp) { any_printed = true; });

EXPECT_TRUE(any_printed);
Expand Down