9
9
#include " InstrumentationRuntimeASan.h"
10
10
11
11
#include " lldb/Breakpoint/StoppointCallbackContext.h"
12
- #include " lldb/Core/Debugger.h"
13
12
#include " lldb/Core/Module.h"
14
13
#include " lldb/Core/PluginInterface.h"
15
14
#include " lldb/Core/PluginManager.h"
16
- #include " lldb/Core/StreamFile.h"
17
- #include " lldb/Core/ValueObject.h"
18
- #include " lldb/Expression/UserExpression.h"
19
- #include " lldb/Interpreter/CommandReturnObject.h"
20
15
#include " lldb/Symbol/Symbol.h"
21
- #include " lldb/Target/InstrumentationRuntimeStopInfo.h"
22
- #include " lldb/Target/StopInfo.h"
23
- #include " lldb/Target/Target.h"
24
- #include " lldb/Target/Thread.h"
16
+ #include " lldb/Target/Process.h"
25
17
#include " lldb/Utility/RegularExpression.h"
26
- #include " lldb/Utility/Stream.h"
27
18
28
- #include " llvm/ADT/StringSwitch .h"
19
+ #include " Plugins/InstrumentationRuntime/Utility/ReportRetriever .h"
29
20
30
21
using namespace lldb ;
31
22
using namespace lldb_private ;
@@ -69,169 +60,6 @@ bool InstrumentationRuntimeASan::CheckIfRuntimeIsValid(
69
60
return symbol != nullptr ;
70
61
}
71
62
72
- const char *address_sanitizer_retrieve_report_data_prefix = R"(
73
- extern "C"
74
- {
75
- int __asan_report_present();
76
- void *__asan_get_report_pc();
77
- void *__asan_get_report_bp();
78
- void *__asan_get_report_sp();
79
- void *__asan_get_report_address();
80
- const char *__asan_get_report_description();
81
- int __asan_get_report_access_type();
82
- size_t __asan_get_report_access_size();
83
- }
84
- )" ;
85
-
86
- const char *address_sanitizer_retrieve_report_data_command = R"(
87
- struct {
88
- int present;
89
- int access_type;
90
- void *pc;
91
- void *bp;
92
- void *sp;
93
- void *address;
94
- size_t access_size;
95
- const char *description;
96
- } t;
97
-
98
- t.present = __asan_report_present();
99
- t.access_type = __asan_get_report_access_type();
100
- t.pc = __asan_get_report_pc();
101
- t.bp = __asan_get_report_bp();
102
- t.sp = __asan_get_report_sp();
103
- t.address = __asan_get_report_address();
104
- t.access_size = __asan_get_report_access_size();
105
- t.description = __asan_get_report_description();
106
- t
107
- )" ;
108
-
109
- StructuredData::ObjectSP InstrumentationRuntimeASan::RetrieveReportData () {
110
- ProcessSP process_sp = GetProcessSP ();
111
- if (!process_sp)
112
- return StructuredData::ObjectSP ();
113
-
114
- ThreadSP thread_sp =
115
- process_sp->GetThreadList ().GetExpressionExecutionThread ();
116
- StackFrameSP frame_sp =
117
- thread_sp->GetSelectedFrame (DoNoSelectMostRelevantFrame);
118
-
119
- if (!frame_sp)
120
- return StructuredData::ObjectSP ();
121
-
122
- EvaluateExpressionOptions options;
123
- options.SetUnwindOnError (true );
124
- options.SetTryAllThreads (true );
125
- options.SetStopOthers (true );
126
- options.SetIgnoreBreakpoints (true );
127
- options.SetTimeout (process_sp->GetUtilityExpressionTimeout ());
128
- options.SetPrefix (address_sanitizer_retrieve_report_data_prefix);
129
- options.SetAutoApplyFixIts (false );
130
- options.SetLanguage (eLanguageTypeObjC_plus_plus);
131
-
132
- ValueObjectSP return_value_sp;
133
- ExecutionContext exe_ctx;
134
- Status eval_error;
135
- frame_sp->CalculateExecutionContext (exe_ctx);
136
- ExpressionResults result = UserExpression::Evaluate (
137
- exe_ctx, options, address_sanitizer_retrieve_report_data_command, " " ,
138
- return_value_sp, eval_error);
139
- if (result != eExpressionCompleted) {
140
- StreamString ss;
141
- ss << " cannot evaluate AddressSanitizer expression:\n " ;
142
- ss << eval_error.AsCString ();
143
- Debugger::ReportWarning (ss.GetString ().str (),
144
- process_sp->GetTarget ().GetDebugger ().GetID ());
145
- return StructuredData::ObjectSP ();
146
- }
147
-
148
- int present = return_value_sp->GetValueForExpressionPath (" .present" )
149
- ->GetValueAsUnsigned (0 );
150
- if (present != 1 )
151
- return StructuredData::ObjectSP ();
152
-
153
- addr_t pc =
154
- return_value_sp->GetValueForExpressionPath (" .pc" )->GetValueAsUnsigned (0 );
155
- addr_t bp =
156
- return_value_sp->GetValueForExpressionPath (" .bp" )->GetValueAsUnsigned (0 );
157
- addr_t sp =
158
- return_value_sp->GetValueForExpressionPath (" .sp" )->GetValueAsUnsigned (0 );
159
- addr_t address = return_value_sp->GetValueForExpressionPath (" .address" )
160
- ->GetValueAsUnsigned (0 );
161
- addr_t access_type =
162
- return_value_sp->GetValueForExpressionPath (" .access_type" )
163
- ->GetValueAsUnsigned (0 );
164
- addr_t access_size =
165
- return_value_sp->GetValueForExpressionPath (" .access_size" )
166
- ->GetValueAsUnsigned (0 );
167
- addr_t description_ptr =
168
- return_value_sp->GetValueForExpressionPath (" .description" )
169
- ->GetValueAsUnsigned (0 );
170
- std::string description;
171
- Status error;
172
- process_sp->ReadCStringFromMemory (description_ptr, description, error);
173
-
174
- StructuredData::Dictionary *dict = new StructuredData::Dictionary ();
175
- dict->AddStringItem (" instrumentation_class" , " AddressSanitizer" );
176
- dict->AddStringItem (" stop_type" , " fatal_error" );
177
- dict->AddIntegerItem (" pc" , pc);
178
- dict->AddIntegerItem (" bp" , bp);
179
- dict->AddIntegerItem (" sp" , sp);
180
- dict->AddIntegerItem (" address" , address);
181
- dict->AddIntegerItem (" access_type" , access_type);
182
- dict->AddIntegerItem (" access_size" , access_size);
183
- dict->AddStringItem (" description" , description);
184
-
185
- return StructuredData::ObjectSP (dict);
186
- }
187
-
188
- std::string
189
- InstrumentationRuntimeASan::FormatDescription (StructuredData::ObjectSP report) {
190
- std::string description = std::string (report->GetAsDictionary ()
191
- ->GetValueForKey (" description" )
192
- ->GetAsString ()
193
- ->GetValue ());
194
- return llvm::StringSwitch<std::string>(description)
195
- .Case (" heap-use-after-free" , " Use of deallocated memory" )
196
- .Case (" heap-buffer-overflow" , " Heap buffer overflow" )
197
- .Case (" stack-buffer-underflow" , " Stack buffer underflow" )
198
- .Case (" initialization-order-fiasco" , " Initialization order problem" )
199
- .Case (" stack-buffer-overflow" , " Stack buffer overflow" )
200
- .Case (" stack-use-after-return" , " Use of stack memory after return" )
201
- .Case (" use-after-poison" , " Use of poisoned memory" )
202
- .Case (" container-overflow" , " Container overflow" )
203
- .Case (" stack-use-after-scope" , " Use of out-of-scope stack memory" )
204
- .Case (" global-buffer-overflow" , " Global buffer overflow" )
205
- .Case (" unknown-crash" , " Invalid memory access" )
206
- .Case (" stack-overflow" , " Stack space exhausted" )
207
- .Case (" null-deref" , " Dereference of null pointer" )
208
- .Case (" wild-jump" , " Jump to non-executable address" )
209
- .Case (" wild-addr-write" , " Write through wild pointer" )
210
- .Case (" wild-addr-read" , " Read from wild pointer" )
211
- .Case (" wild-addr" , " Access through wild pointer" )
212
- .Case (" signal" , " Deadly signal" )
213
- .Case (" double-free" , " Deallocation of freed memory" )
214
- .Case (" new-delete-type-mismatch" ,
215
- " Deallocation size different from allocation size" )
216
- .Case (" bad-free" , " Deallocation of non-allocated memory" )
217
- .Case (" alloc-dealloc-mismatch" ,
218
- " Mismatch between allocation and deallocation APIs" )
219
- .Case (" bad-malloc_usable_size" , " Invalid argument to malloc_usable_size" )
220
- .Case (" bad-__sanitizer_get_allocated_size" ,
221
- " Invalid argument to __sanitizer_get_allocated_size" )
222
- .Case (" param-overlap" ,
223
- " Call to function disallowing overlapping memory ranges" )
224
- .Case (" negative-size-param" , " Negative size used when accessing memory" )
225
- .Case (" bad-__sanitizer_annotate_contiguous_container" ,
226
- " Invalid argument to __sanitizer_annotate_contiguous_container" )
227
- .Case (" odr-violation" , " Symbol defined in multiple translation units" )
228
- .Case (
229
- " invalid-pointer-pair" ,
230
- " Comparison or arithmetic on pointers from different memory regions" )
231
- // for unknown report codes just show the code
232
- .Default (" AddressSanitizer detected: " + description);
233
- }
234
-
235
63
bool InstrumentationRuntimeASan::NotifyBreakpointHit (
236
64
void *baton, StoppointCallbackContext *context, user_id_t break_id,
237
65
user_id_t break_loc_id) {
@@ -244,32 +72,8 @@ bool InstrumentationRuntimeASan::NotifyBreakpointHit(
244
72
245
73
ProcessSP process_sp = instance->GetProcessSP ();
246
74
247
- if (process_sp->GetModIDRef ().IsLastResumeForUserExpression ())
248
- return false ;
249
-
250
- StructuredData::ObjectSP report = instance->RetrieveReportData ();
251
- std::string description;
252
- if (report) {
253
- description = instance->FormatDescription (report);
254
- }
255
- // Make sure this is the right process
256
- if (process_sp && process_sp == context->exe_ctx_ref .GetProcessSP ()) {
257
- ThreadSP thread_sp = context->exe_ctx_ref .GetThreadSP ();
258
- if (thread_sp)
259
- thread_sp->SetStopInfo (InstrumentationRuntimeStopInfo::
260
- CreateStopReasonWithInstrumentationData (
261
- *thread_sp, description, report));
262
-
263
- StreamFileSP stream_sp (
264
- process_sp->GetTarget ().GetDebugger ().GetOutputStreamSP ());
265
- if (stream_sp) {
266
- stream_sp->Printf (" AddressSanitizer report breakpoint hit. Use 'thread "
267
- " info -s' to get extended information about the "
268
- " report.\n " );
269
- }
270
- return true ; // Return true to stop the target
271
- } else
272
- return false ; // Let target run
75
+ return ReportRetriever::NotifyBreakpointHit (process_sp, context, break_id,
76
+ break_loc_id);
273
77
}
274
78
275
79
void InstrumentationRuntimeASan::Activate () {
@@ -280,29 +84,14 @@ void InstrumentationRuntimeASan::Activate() {
280
84
if (!process_sp)
281
85
return ;
282
86
283
- ConstString symbol_name (" _ZN6__asanL7AsanDieEv" );
284
- const Symbol *symbol = GetRuntimeModuleSP ()->FindFirstSymbolWithNameAndType (
285
- symbol_name, eSymbolTypeCode);
286
-
287
- if (symbol == nullptr )
288
- return ;
87
+ Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint (
88
+ GetRuntimeModuleSP (), process_sp, ConstString (" _ZN6__asanL7AsanDieEv" ));
289
89
290
- if (!symbol-> ValueIsAddress () || !symbol-> GetAddressRef (). IsValid () )
90
+ if (!breakpoint )
291
91
return ;
292
92
293
- Target &target = process_sp->GetTarget ();
294
- addr_t symbol_address = symbol->GetAddressRef ().GetOpcodeLoadAddress (&target);
295
-
296
- if (symbol_address == LLDB_INVALID_ADDRESS)
297
- return ;
298
-
299
- const bool internal = true ;
300
- const bool hardware = false ;
301
93
const bool sync = false ;
302
- Breakpoint *breakpoint =
303
- process_sp->GetTarget ()
304
- .CreateBreakpoint (symbol_address, internal, hardware)
305
- .get ();
94
+
306
95
breakpoint->SetCallback (InstrumentationRuntimeASan::NotifyBreakpointHit, this ,
307
96
sync);
308
97
breakpoint->SetBreakpointKind (" address-sanitizer-report" );
@@ -312,12 +101,13 @@ void InstrumentationRuntimeASan::Activate() {
312
101
}
313
102
314
103
void InstrumentationRuntimeASan::Deactivate () {
315
- if (GetBreakpointID () != LLDB_INVALID_BREAK_ID) {
316
- ProcessSP process_sp = GetProcessSP ();
317
- if (process_sp) {
318
- process_sp->GetTarget ().RemoveBreakpointByID (GetBreakpointID ());
319
- SetBreakpointID (LLDB_INVALID_BREAK_ID);
320
- }
321
- }
322
104
SetActive (false );
105
+
106
+ if (GetBreakpointID () == LLDB_INVALID_BREAK_ID)
107
+ return ;
108
+
109
+ if (ProcessSP process_sp = GetProcessSP ()) {
110
+ process_sp->GetTarget ().RemoveBreakpointByID (GetBreakpointID ());
111
+ SetBreakpointID (LLDB_INVALID_BREAK_ID);
112
+ }
323
113
}
0 commit comments