Skip to content

Commit 37ade2d

Browse files
authored
Merge pull request #757 from medismailben/apple/stable/20200108
[lldb] Fix+re-enable Assert StackFrame Recognizer on Linux
2 parents e4de877 + 956e050 commit 37ade2d

File tree

7 files changed

+70
-68
lines changed

7 files changed

+70
-68
lines changed

lldb/include/lldb/Target/StackFrameRecognizer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ class ScriptedStackFrameRecognizer : public StackFrameRecognizer {
101101
class StackFrameRecognizerManager {
102102
public:
103103
static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
104-
ConstString module,
105-
ConstString symbol,
104+
ConstString module, ConstString symbol,
105+
ConstString alternate_symbol,
106106
bool first_instruction_only = true);
107107

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

118119
static bool RemoveRecognizerWithID(uint32_t recognizer_id);
119120

lldb/source/Commands/CommandObjectFrame.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command,
882882
} else {
883883
auto module = ConstString(m_options.m_module);
884884
auto func = ConstString(m_options.m_function);
885-
StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func);
885+
StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func, {});
886886
}
887887
#endif
888888

@@ -961,12 +961,13 @@ class CommandObjectFrameRecognizerList : public CommandObjectParsed {
961961
StackFrameRecognizerManager::ForEach(
962962
[&result, &any_printed](uint32_t recognizer_id, std::string name,
963963
std::string function, std::string symbol,
964-
bool regexp) {
964+
std::string alternate_symbol, bool regexp) {
965965
if (name == "")
966966
name = "(internal)";
967967
result.GetOutputStream().Printf(
968-
"%d: %s, module %s, function %s%s\n", recognizer_id, name.c_str(),
969-
function.c_str(), symbol.c_str(), regexp ? " (regexp)" : "");
968+
"%d: %s, module %s, function %s{%s}%s\n", recognizer_id,
969+
name.c_str(), function.c_str(), symbol.c_str(),
970+
alternate_symbol.c_str(), regexp ? " (regexp)" : "");
970971
any_printed = true;
971972
});
972973

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2723,6 +2723,7 @@ static void RegisterObjCExceptionRecognizer() {
27232723
std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
27242724
StackFrameRecognizerManager::AddRecognizer(
27252725
StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
2726-
module.GetFilename(), function, /*first_instruction_only*/ true);
2726+
module.GetFilename(), function, /*alternate_symbol*/ {},
2727+
/*first_instruction_only*/ true);
27272728
});
27282729
}

lldb/source/Target/AssertFrameRecognizer.cpp

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,22 @@ using namespace lldb;
1616
using namespace lldb_private;
1717

1818
namespace lldb_private {
19-
/// Checkes if the module containing a symbol has debug info.
20-
///
21-
/// \param[in] target
22-
/// The target containing the module.
23-
/// \param[in] module_spec
24-
/// The module spec that should contain the symbol.
25-
/// \param[in] symbol_name
26-
/// The symbol's name that should be contained in the debug info.
27-
/// \return
28-
/// If \b true the symbol was found, \b false otherwise.
29-
bool ModuleHasDebugInfo(Target &target, FileSpec &module_spec,
30-
StringRef symbol_name) {
31-
ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec);
32-
33-
if (!module_sp)
34-
return false;
35-
36-
return module_sp->FindFirstSymbolWithNameAndType(ConstString(symbol_name));
37-
}
38-
3919
/// Fetches the abort frame location depending on the current platform.
4020
///
4121
/// \param[in] process_sp
4222
/// The process that is currently aborting. This will give us information on
4323
/// the target and the platform.
4424
/// \return
4525
/// If the platform is supported, returns an optional tuple containing
46-
/// the abort module as a \a FileSpec and the symbol name as a \a StringRef.
26+
/// the abort module as a \a FileSpec and two symbol names as two \a
27+
/// StringRef. The second \a StringRef may be empty.
4728
/// Otherwise, returns \a llvm::None.
48-
llvm::Optional<std::tuple<FileSpec, StringRef>>
29+
llvm::Optional<std::tuple<FileSpec, StringRef, StringRef>>
4930
GetAbortLocation(Process *process) {
5031
Target &target = process->GetTarget();
5132

5233
FileSpec module_spec;
53-
StringRef symbol_name;
34+
StringRef symbol_name, alternate_symbol_name;
5435

5536
switch (target.GetArchitecture().GetTriple().getOS()) {
5637
case llvm::Triple::Darwin:
@@ -60,17 +41,16 @@ GetAbortLocation(Process *process) {
6041
break;
6142
case llvm::Triple::Linux:
6243
module_spec = FileSpec("libc.so.6");
63-
symbol_name = "__GI_raise";
64-
if (!ModuleHasDebugInfo(target, module_spec, symbol_name))
65-
symbol_name = "raise";
44+
symbol_name = "raise";
45+
alternate_symbol_name = "__GI_raise";
6646
break;
6747
default:
6848
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
6949
LLDB_LOG(log, "AssertFrameRecognizer::GetAbortLocation Unsupported OS");
7050
return llvm::None;
7151
}
7252

73-
return std::make_tuple(module_spec, symbol_name);
53+
return std::make_tuple(module_spec, symbol_name, alternate_symbol_name);
7454
}
7555

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

9070
FileSpec module_spec;
91-
StringRef symbol_name;
71+
StringRef symbol_name, alternate_symbol_name;
9272

9373
switch (target.GetArchitecture().GetTriple().getOS()) {
9474
case llvm::Triple::Darwin:
@@ -98,17 +78,16 @@ GetAssertLocation(Process *process) {
9878
break;
9979
case llvm::Triple::Linux:
10080
module_spec = FileSpec("libc.so.6");
101-
symbol_name = "__GI___assert_fail";
102-
if (!ModuleHasDebugInfo(target, module_spec, symbol_name))
103-
symbol_name = "__assert_fail";
81+
symbol_name = "__assert_fail";
82+
alternate_symbol_name = "__GI___assert_fail";
10483
break;
10584
default:
10685
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
10786
LLDB_LOG(log, "AssertFrameRecognizer::GetAssertLocation Unsupported OS");
10887
return llvm::None;
10988
}
11089

111-
return std::make_tuple(module_spec, symbol_name);
90+
return std::make_tuple(module_spec, symbol_name, alternate_symbol_name);
11291
}
11392

11493
void RegisterAssertFrameRecognizer(Process *process) {
@@ -120,12 +99,14 @@ void RegisterAssertFrameRecognizer(Process *process) {
12099
return;
121100

122101
FileSpec module_spec;
123-
StringRef function_name;
124-
std::tie(module_spec, function_name) = *abort_location;
102+
StringRef function_name, alternate_function_name;
103+
std::tie(module_spec, function_name, alternate_function_name) =
104+
*abort_location;
125105

126106
StackFrameRecognizerManager::AddRecognizer(
127107
StackFrameRecognizerSP(new AssertFrameRecognizer()),
128-
module_spec.GetFilename(), ConstString(function_name), false);
108+
module_spec.GetFilename(), ConstString(function_name),
109+
ConstString(alternate_function_name), /*first_instruction_only*/ false);
129110
});
130111
}
131112

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

144125
FileSpec module_spec;
145-
StringRef function_name;
146-
std::tie(module_spec, function_name) = *assert_location;
126+
StringRef function_name, alternate_function_name;
127+
std::tie(module_spec, function_name, alternate_function_name) =
128+
*assert_location;
147129

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

166-
if (sym_ctx.module_sp->GetFileSpec().FileEquals(module_spec) &&
167-
sym_ctx.GetFunctionName() == ConstString(function_name)) {
148+
if (!sym_ctx.module_sp->GetFileSpec().FileEquals(module_spec))
149+
continue;
150+
151+
ConstString func_name = sym_ctx.GetFunctionName();
152+
if (func_name == ConstString(function_name) ||
153+
alternate_function_name.empty() ||
154+
func_name == ConstString(alternate_function_name)) {
168155

169156
// We go a frame beyond the assert location because the most relevant
170157
// frame for the user is the one in which the assert function was called.

lldb/source/Target/StackFrameRecognizer.cpp

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,28 @@ ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {
5050

5151
class StackFrameRecognizerManagerImpl {
5252
public:
53-
void AddRecognizer(StackFrameRecognizerSP recognizer,
54-
ConstString module, ConstString symbol,
53+
void AddRecognizer(StackFrameRecognizerSP recognizer, ConstString module,
54+
ConstString symbol, ConstString alternate_symbol,
5555
bool first_instruction_only) {
56-
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(),
57-
symbol, RegularExpressionSP(),
56+
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer,
57+
false, module, RegularExpressionSP(), symbol,
58+
alternate_symbol, RegularExpressionSP(),
5859
first_instruction_only});
5960
}
6061

6162
void AddRecognizer(StackFrameRecognizerSP recognizer,
6263
RegularExpressionSP module, RegularExpressionSP symbol,
6364
bool first_instruction_only) {
64-
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), module,
65+
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer,
66+
true, ConstString(), module, ConstString(),
6567
ConstString(), symbol, first_instruction_only});
6668
}
6769

6870
void ForEach(
69-
std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
70-
std::string symbol, bool regexp)> const &callback) {
71+
std::function<void(uint32_t recognized_id, std::string recognizer_name,
72+
std::string module, std::string symbol,
73+
std::string alternate_symbol, bool regexp)> const
74+
&callback) {
7175
for (auto entry : m_recognizers) {
7276
if (entry.is_regexp) {
7377
std::string module_name;
@@ -79,11 +83,12 @@ class StackFrameRecognizerManagerImpl {
7983
symbol_name = entry.symbol_regexp->GetText().str();
8084

8185
callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
82-
symbol_name, true);
86+
symbol_name, {}, true);
8387

8488
} else {
85-
callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(),
86-
entry.symbol.GetCString(), false);
89+
callback(entry.recognizer_id, entry.recognizer->GetName(),
90+
entry.module.GetCString(), entry.symbol.GetCString(),
91+
entry.alternate_symbol.GetCString(), false);
8792
}
8893
}
8994
}
@@ -120,7 +125,10 @@ class StackFrameRecognizerManagerImpl {
120125
if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue;
121126

122127
if (entry.symbol)
123-
if (entry.symbol != function_name) continue;
128+
if (entry.symbol != function_name &&
129+
(!entry.alternate_symbol ||
130+
entry.alternate_symbol != function_name))
131+
continue;
124132

125133
if (entry.symbol_regexp)
126134
if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
@@ -149,6 +157,7 @@ class StackFrameRecognizerManagerImpl {
149157
ConstString module;
150158
RegularExpressionSP module_regexp;
151159
ConstString symbol;
160+
ConstString alternate_symbol;
152161
RegularExpressionSP symbol_regexp;
153162
bool first_instruction_only;
154163
};
@@ -163,10 +172,10 @@ StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() {
163172
}
164173

165174
void StackFrameRecognizerManager::AddRecognizer(
166-
StackFrameRecognizerSP recognizer, ConstString module,
167-
ConstString symbol, bool first_instruction_only) {
168-
GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
169-
first_instruction_only);
175+
StackFrameRecognizerSP recognizer, ConstString module, ConstString symbol,
176+
ConstString alternate_symbol, bool first_instruction_only) {
177+
GetStackFrameRecognizerManagerImpl().AddRecognizer(
178+
recognizer, module, symbol, alternate_symbol, first_instruction_only);
170179
}
171180

172181
void StackFrameRecognizerManager::AddRecognizer(
@@ -177,8 +186,10 @@ void StackFrameRecognizerManager::AddRecognizer(
177186
}
178187

179188
void StackFrameRecognizerManager::ForEach(
180-
std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
181-
std::string symbol, bool regexp)> const &callback) {
189+
std::function<void(uint32_t recognized_id, std::string recognizer_name,
190+
std::string module, std::string symbol,
191+
std::string alternate_symbol, bool regexp)> const
192+
&callback) {
182193
GetStackFrameRecognizerManagerImpl().ForEach(callback);
183194
}
184195

lldb/test/Shell/Recognizer/assert.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# UNSUPPORTED: system-windows, system-linux
1+
# UNSUPPORTED: system-windows
22
# RUN: %clang_host -g -O0 %S/Inputs/assert.c -o %t.out
33
# RUN: %lldb -b -s %s %t.out | FileCheck %s
44
run

lldb/unittests/Target/StackFrameRecognizerTest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ TEST_F(StackFrameRecognizerTest, NullModuleRegex) {
7777
StackFrameRecognizerManager::ForEach(
7878
[&any_printed](uint32_t recognizer_id, std::string name,
7979
std::string function, std::string symbol,
80+
std::string alternate_symbol,
8081
bool regexp) { any_printed = true; });
8182

8283
EXPECT_TRUE(any_printed);

0 commit comments

Comments
 (0)