[InstrumentationRuntime] Refactor the API (Part 1/N) (NFCI)

Adapters for instrumentation runtimes have to do two basic things:

  1) Load a runtime library.
  2) Install breakpoints in that library.

This logic is duplicated in the adapters for asan and tsan. Factor it
out and document bits of it to make it easier to add new adapters.

I tested this with check-lldb, and double-checked
testcases/functionalities/{a,t}san.

Differential Revision: https://reviews.llvm.org/D23043

llvm-svn: 278367
This commit is contained in:
Vedant Kumar
2016-08-11 17:28:33 +00:00
parent 76837df6ff
commit a4fa2e299a
6 changed files with 87 additions and 103 deletions

View File

@@ -17,6 +17,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
#include "lldb/lldb-types.h"
#include "lldb/Core/PluginInterface.h"
@@ -30,16 +31,77 @@ class InstrumentationRuntime :
public std::enable_shared_from_this<InstrumentationRuntime>,
public PluginInterface
{
/// The instrumented process.
lldb::ProcessWP m_process_wp;
/// The module containing the instrumentation runtime.
lldb::ModuleSP m_runtime_module;
/// The breakpoint in the instrumentation runtime.
lldb::user_id_t m_breakpoint_id;
/// Indicates whether or not breakpoints have been registered in the instrumentation runtime.
bool m_is_active;
protected:
InstrumentationRuntime(const lldb::ProcessSP &process_sp)
: m_process_wp(), m_runtime_module(), m_breakpoint_id(0), m_is_active(false)
{
if (process_sp)
m_process_wp = process_sp;
}
lldb::ProcessSP
GetProcessSP()
{
return m_process_wp.lock();
}
lldb::ModuleSP
GetRuntimeModuleSP()
{
return m_runtime_module;
}
void
SetRuntimeModuleSP(lldb::ModuleSP module_sp)
{
m_runtime_module = module_sp;
}
lldb::user_id_t
GetBreakpointID() const
{
return m_breakpoint_id;
}
void
SetBreakpointID(lldb::user_id_t ID)
{
m_breakpoint_id = ID;
}
void
SetActive(bool IsActive)
{
m_is_active = IsActive;
}
public:
static void
ModulesDidLoad(lldb_private::ModuleList &module_list, Process *process, InstrumentationRuntimeCollection &runtimes);
/// Look for the instrumentation runtime in \p module_list. Register and activate the runtime if this hasn't already
/// been done.
virtual void
ModulesDidLoad(lldb_private::ModuleList &module_list);
virtual bool
IsActive();
ModulesDidLoad(lldb_private::ModuleList &module_list) = 0;
bool
IsActive() const
{
return m_is_active;
}
virtual lldb::ThreadCollectionSP
GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info);

View File

@@ -63,16 +63,6 @@ AddressSanitizerRuntime::GetTypeStatic()
return eInstrumentationRuntimeTypeAddressSanitizer;
}
AddressSanitizerRuntime::AddressSanitizerRuntime(const ProcessSP &process_sp) :
m_is_active(false),
m_runtime_module(),
m_process_wp(),
m_breakpoint_id(0)
{
if (process_sp)
m_process_wp = process_sp;
}
AddressSanitizerRuntime::~AddressSanitizerRuntime()
{
Deactivate();
@@ -93,7 +83,7 @@ AddressSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
if (IsActive())
return;
if (m_runtime_module) {
if (GetRuntimeModuleSP()) {
Activate();
return;
}
@@ -112,7 +102,7 @@ AddressSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
{
if (ModuleContainsASanRuntime(module_pointer))
{
m_runtime_module = module_pointer->shared_from_this();
SetRuntimeModuleSP(module_pointer->shared_from_this());
Activate();
return;
}
@@ -120,12 +110,6 @@ AddressSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
}
}
bool
AddressSanitizerRuntime::IsActive()
{
return m_is_active;
}
#define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000
const char *
address_sanitizer_retrieve_report_data_prefix = R"(
@@ -305,7 +289,7 @@ AddressSanitizerRuntime::NotifyBreakpointHit(void *baton, StoppointCallbackConte
void
AddressSanitizerRuntime::Activate()
{
if (m_is_active)
if (IsActive())
return;
ProcessSP process_sp = GetProcessSP();
@@ -313,7 +297,7 @@ AddressSanitizerRuntime::Activate()
return;
ConstString symbol_name ("__asan::AsanDie()");
const Symbol *symbol = m_runtime_module->FindFirstSymbolWithNameAndType (symbol_name, eSymbolTypeCode);
const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType (symbol_name, eSymbolTypeCode);
if (symbol == NULL)
return;
@@ -332,7 +316,7 @@ AddressSanitizerRuntime::Activate()
Breakpoint *breakpoint = process_sp->GetTarget().CreateBreakpoint(symbol_address, internal, hardware).get();
breakpoint->SetCallback (AddressSanitizerRuntime::NotifyBreakpointHit, this, true);
breakpoint->SetBreakpointKind ("address-sanitizer-report");
m_breakpoint_id = breakpoint->GetID();
SetBreakpointID(breakpoint->GetID());
StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
if (stream_sp)
@@ -340,20 +324,20 @@ AddressSanitizerRuntime::Activate()
stream_sp->Printf ("AddressSanitizer debugger support is active. Memory error breakpoint has been installed and you can now use the 'memory history' command.\n");
}
m_is_active = true;
SetActive(true);
}
void
AddressSanitizerRuntime::Deactivate()
{
if (m_breakpoint_id != LLDB_INVALID_BREAK_ID)
if (GetBreakpointID() != LLDB_INVALID_BREAK_ID)
{
ProcessSP process_sp = GetProcessSP();
if (process_sp)
{
process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
m_breakpoint_id = LLDB_INVALID_BREAK_ID;
process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
SetBreakpointID(LLDB_INVALID_BREAK_ID);
}
}
m_is_active = false;
SetActive(false);
}

View File

@@ -59,17 +59,8 @@ public:
void
ModulesDidLoad(lldb_private::ModuleList &module_list) override;
bool
IsActive() override;
private:
AddressSanitizerRuntime(const lldb::ProcessSP &process_sp);
lldb::ProcessSP
GetProcessSP ()
{
return m_process_wp.lock();
}
AddressSanitizerRuntime(const lldb::ProcessSP &process_sp) : lldb_private::InstrumentationRuntime(process_sp) {}
void
Activate();
@@ -85,11 +76,6 @@ private:
std::string
FormatDescription(StructuredData::ObjectSP report);
bool m_is_active;
lldb::ModuleSP m_runtime_module;
lldb::ProcessWP m_process_wp;
lldb::user_id_t m_breakpoint_id;
};
} // namespace lldb_private

View File

@@ -68,16 +68,6 @@ ThreadSanitizerRuntime::GetTypeStatic()
return eInstrumentationRuntimeTypeThreadSanitizer;
}
ThreadSanitizerRuntime::ThreadSanitizerRuntime(const ProcessSP &process_sp) :
m_is_active(false),
m_runtime_module_wp(),
m_process_wp(),
m_breakpoint_id(0)
{
if (process_sp)
m_process_wp = process_sp;
}
ThreadSanitizerRuntime::~ThreadSanitizerRuntime()
{
Deactivate();
@@ -113,7 +103,7 @@ ThreadSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
{
if (ModuleContainsTSanRuntime(module_sp))
{
m_runtime_module_wp = module_sp;
SetRuntimeModuleSP(module_sp);
Activate();
return false; // Stop iterating
}
@@ -123,12 +113,6 @@ ThreadSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
});
}
bool
ThreadSanitizerRuntime::IsActive()
{
return m_is_active;
}
#define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000
const char *
@@ -732,7 +716,7 @@ ThreadSanitizerRuntime::NotifyBreakpointHit(void *baton, StoppointCallbackContex
void
ThreadSanitizerRuntime::Activate()
{
if (m_is_active)
if (IsActive())
return;
ProcessSP process_sp = GetProcessSP();
@@ -759,7 +743,7 @@ ThreadSanitizerRuntime::Activate()
Breakpoint *breakpoint = process_sp->GetTarget().CreateBreakpoint(symbol_address, internal, hardware).get();
breakpoint->SetCallback (ThreadSanitizerRuntime::NotifyBreakpointHit, this, true);
breakpoint->SetBreakpointKind ("thread-sanitizer-report");
m_breakpoint_id = breakpoint->GetID();
SetBreakpointID(breakpoint->GetID());
StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
if (stream_sp)
@@ -767,22 +751,22 @@ ThreadSanitizerRuntime::Activate()
stream_sp->Printf ("ThreadSanitizer debugger support is active.\n");
}
m_is_active = true;
SetActive(true);
}
void
ThreadSanitizerRuntime::Deactivate()
{
if (m_breakpoint_id != LLDB_INVALID_BREAK_ID)
if (GetBreakpointID() != LLDB_INVALID_BREAK_ID)
{
ProcessSP process_sp = GetProcessSP();
if (process_sp)
{
process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
m_breakpoint_id = LLDB_INVALID_BREAK_ID;
process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
SetBreakpointID(LLDB_INVALID_BREAK_ID);
}
}
m_is_active = false;
SetActive(false);
}
static std::string

View File

@@ -17,7 +17,6 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Core/StructuredData.h"
namespace lldb_private {
@@ -60,26 +59,11 @@ public:
void
ModulesDidLoad(lldb_private::ModuleList &module_list) override;
bool
IsActive() override;
lldb::ThreadCollectionSP
GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
private:
ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp);
lldb::ProcessSP
GetProcessSP ()
{
return m_process_wp.lock();
}
lldb::ModuleSP
GetRuntimeModuleSP ()
{
return m_runtime_module_wp.lock();
}
ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp) : lldb_private::InstrumentationRuntime(process_sp) {}
void
Activate();
@@ -107,11 +91,6 @@ private:
lldb::addr_t
GetFirstNonInternalFramePc(StructuredData::ObjectSP trace);
bool m_is_active;
lldb::ModuleWP m_runtime_module_wp;
lldb::ProcessWP m_process_wp;
lldb::user_id_t m_breakpoint_id;
};
} // namespace lldb_private

View File

@@ -40,17 +40,6 @@ InstrumentationRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list, ll
}
}
void
InstrumentationRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list)
{
}
bool
InstrumentationRuntime::IsActive()
{
return false;
}
lldb::ThreadCollectionSP
InstrumentationRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info)
{