diff options
Diffstat (limited to 'source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp')
-rw-r--r-- | source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp | 109 |
1 files changed, 68 insertions, 41 deletions
diff --git a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index c57519871624..a9d13ac79c37 100644 --- a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -12,8 +12,10 @@ #include "lldb/Target/MemoryHistory.h" #include "lldb/lldb-private.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Expression/UserExpression.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" @@ -22,6 +24,8 @@ #include "Plugins/Process/Utility/HistoryThread.h" #include "lldb/Core/ValueObject.h" +#include <sstream> + using namespace lldb; using namespace lldb_private; @@ -34,7 +38,7 @@ MemoryHistoryASan::CreateInstance (const ProcessSP &process_sp) Target & target = process_sp->GetTarget(); const ModuleList &target_modules = target.GetImages(); - Mutex::Locker modules_locker(target_modules.GetMutex()); + std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); const size_t num_modules = target_modules.GetSize(); for (size_t i = 0; i < num_modules; ++i) { @@ -80,8 +84,14 @@ MemoryHistoryASan::MemoryHistoryASan(const ProcessSP &process_sp) } const char * -memory_history_asan_command_format = R"( - struct t { +memory_history_asan_command_prefix = R"( + extern "C" + { + size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size, int *thread_id); + size_t __asan_get_free_stack(void *addr, void **trace, size_t size, int *thread_id); + } + + struct data { void *alloc_trace[256]; size_t alloc_count; int alloc_tid; @@ -89,10 +99,15 @@ memory_history_asan_command_format = R"( void *free_trace[256]; size_t free_count; int free_tid; - } t; + }; +)"; + +const char * +memory_history_asan_command_format = R"( + data t; - t.alloc_count = ((size_t (*) (void *, void **, size_t, int *))__asan_get_alloc_stack)((void *)0x%)" PRIx64 R"(, t.alloc_trace, 256, &t.alloc_tid); - t.free_count = ((size_t (*) (void *, void **, size_t, int *))__asan_get_free_stack)((void *)0x%)" PRIx64 R"(, t.free_trace, 256, &t.free_tid); + t.alloc_count = __asan_get_alloc_stack((void *)0x%)" PRIx64 R"(, t.alloc_trace, 256, &t.alloc_tid); + t.free_count = __asan_get_free_stack((void *)0x%)" PRIx64 R"(, t.free_trace, 256, &t.free_tid); t; )"; @@ -110,7 +125,7 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp, ValueObject return; int count = count_sp->GetValueAsUnsigned(0); - tid_t tid = tid_sp->GetValueAsUnsigned(0); + tid_t tid = tid_sp->GetValueAsUnsigned(0) + 1; if (count <= 0) return; @@ -131,8 +146,9 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp, ValueObject HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, 0, false); ThreadSP new_thread_sp(history_thread); - // let's use thread name for the type of history thread, since history threads don't have names anyway - history_thread->SetThreadName(thread_name); + std::ostringstream thread_name_with_number; + thread_name_with_number << thread_name << " Thread " << tid; + history_thread->SetThreadName(thread_name_with_number.str().c_str()); // Save this in the Process' ExtendedThreadList so a strong pointer retains the object process_sp->GetExtendedThreadList().AddThread (new_thread_sp); result.push_back(new_thread_sp); @@ -146,38 +162,49 @@ MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) HistoryThreads result; ProcessSP process_sp = m_process_wp.lock(); - if (process_sp) - { - ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); - - if (thread_sp) - { - StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); - - if (frame_sp) - { - ExecutionContext exe_ctx (frame_sp); - ValueObjectSP return_value_sp; - StreamString expr; - expr.Printf(memory_history_asan_command_format, address, address); - - EvaluateExpressionOptions options; - options.SetUnwindOnError(true); - options.SetTryAllThreads(true); - options.SetStopOthers(true); - options.SetIgnoreBreakpoints(true); - options.SetTimeoutUsec(GET_STACK_FUNCTION_TIMEOUT_USEC); - - if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), return_value_sp, options) == eExpressionCompleted) - { - if (return_value_sp) - { - CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "free", "Memory deallocated at", result); - CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "alloc", "Memory allocated at", result); - } - } - } - } + if (! process_sp) + return result; + + ThreadSP thread_sp = process_sp->GetThreadList().GetExpressionExecutionThread(); + if (!thread_sp) + return result; + + StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + if (!frame_sp) + return result; + + ExecutionContext exe_ctx (frame_sp); + ValueObjectSP return_value_sp; + StreamString expr; + Error eval_error; + expr.Printf(memory_history_asan_command_format, address, address); + + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetTryAllThreads(true); + options.SetStopOthers(true); + options.SetIgnoreBreakpoints(true); + options.SetTimeoutUsec(GET_STACK_FUNCTION_TIMEOUT_USEC); + options.SetPrefix(memory_history_asan_command_prefix); + options.SetAutoApplyFixIts(false); + options.SetLanguage(eLanguageTypeObjC_plus_plus); + + ExpressionResults expr_result = UserExpression::Evaluate (exe_ctx, + options, + expr.GetData(), + "", + return_value_sp, + eval_error); + if (expr_result != eExpressionCompleted) { + process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", eval_error.AsCString()); + return result; } + + if (!return_value_sp) + return result; + + CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "free", "Memory deallocated by", result); + CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "alloc", "Memory allocated by", result); + return result; } |