FWIW this didn't even vaguely build on anything other than xcode. Fixed thusly:
dzur:~/sources/llvm/tools/lldb> svn ci lib/Makefile source/ Sending lib/Makefile Sending source/CMakeLists.txt Sending source/Plugins/Makefile Transmitting file data ... Committed revision 219554. -eric On Fri, Oct 10, 2014 at 4:43 PM, Kuba Brecka <[email protected]> wrote: > Author: kuba.brecka > Date: Fri Oct 10 18:43:03 2014 > New Revision: 219546 > > URL: http://llvm.org/viewvc/llvm-project?rev=219546&view=rev > Log: > LLDB AddressSanitizer instrumentation runtime plugin, breakpint on error and > report data extraction > > Reviewed at http://reviews.llvm.org/D5592 > > This patch gives LLDB some ability to interact with AddressSanitizer runtime > library, on top of what we already have (historical memory stack traces > provided by ASan). Namely, that's the ability to stop on an error caught by > ASan, and access the report information that are associated with it. The > report information is also exposed into SB API. > > More precisely this patch... > > adds a new plugin type, InstrumentationRuntime, which should serve as a > generic superclass for other instrumentation runtime libraries, these plugins > get notified when modules are loaded, so they get a chance to "activate" when > a specific dynamic library is loaded > an instance of this plugin type, AddressSanitizerRuntime, which activates > itself when it sees the ASan dynamic library or founds ASan statically linked > in the executable > adds a collection of these plugins into the Process class > AddressSanitizerRuntime sets an internal breakpoint on __asan::AsanDie(), and > when this breakpoint gets hit, it retrieves the report information from ASan > this breakpoint is then exposed as a new StopReason, > eStopReasonInstrumentation, with a new StopInfo subclass, > InstrumentationRuntimeStopInfo > the StopInfo superclass is extended with a m_extended_info field (it's a > StructuredData::ObjectSP), that can hold arbitrary JSON-like data, which is > the way the new plugin provides the report data > the "thread info" command now accepts a "-s" flag that prints out the JSON > data of a stop reason (same way the "-j" flag works now) > SBThread has a new API, GetStopReasonExtendedInfoAsJSON, which dumps the JSON > string into a SBStream > adds a test case for all of this > I plan to also get rid of the original ASan plugin (memory history stack > traces) and use an instance of AddressSanitizerRuntime for that purpose. > > Kuba > > > Added: > lldb/trunk/include/lldb/Target/InstrumentationRuntime.h > lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h > lldb/trunk/source/Plugins/InstrumentationRuntime/ > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/ > > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp > > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h > > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/CMakeLists.txt > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile > lldb/trunk/source/Plugins/InstrumentationRuntime/CMakeLists.txt > lldb/trunk/source/Target/InstrumentationRuntime.cpp > lldb/trunk/source/Target/InstrumentationRuntimeStopInfo.cpp > lldb/trunk/test/functionalities/asan/TestMemoryHistory.py > - copied unchanged from r219545, > lldb/trunk/test/functionalities/asan/TestAsan.py > lldb/trunk/test/functionalities/asan/TestReportData.py > Removed: > lldb/trunk/test/functionalities/asan/TestAsan.py > Modified: > lldb/trunk/include/lldb/API/SBThread.h > lldb/trunk/include/lldb/Core/PluginManager.h > lldb/trunk/include/lldb/Target/Process.h > lldb/trunk/include/lldb/Target/StopInfo.h > lldb/trunk/include/lldb/Target/Thread.h > lldb/trunk/include/lldb/lldb-enumerations.h > lldb/trunk/include/lldb/lldb-forward.h > lldb/trunk/include/lldb/lldb-private-interfaces.h > lldb/trunk/lldb.xcodeproj/project.pbxproj > lldb/trunk/scripts/Python/interface/SBThread.i > lldb/trunk/source/API/SBThread.cpp > lldb/trunk/source/Commands/CommandObjectThread.cpp > lldb/trunk/source/Core/Debugger.cpp > lldb/trunk/source/Core/PluginManager.cpp > lldb/trunk/source/Target/CMakeLists.txt > lldb/trunk/source/Target/Process.cpp > lldb/trunk/source/Target/StopInfo.cpp > lldb/trunk/source/Target/Thread.cpp > lldb/trunk/source/lldb.cpp > lldb/trunk/test/functionalities/asan/main.c > > Modified: lldb/trunk/include/lldb/API/SBThread.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/API/SBThread.h (original) > +++ lldb/trunk/include/lldb/API/SBThread.h Fri Oct 10 18:43:03 2014 > @@ -78,7 +78,10 @@ public: > > //-------------------------------------------------------------------------- > uint64_t > GetStopReasonDataAtIndex(uint32_t idx); > - > + > + bool > + GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream); > + > size_t > GetStopDescription (char *dst, size_t dst_len); > > > Modified: lldb/trunk/include/lldb/Core/PluginManager.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/PluginManager.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/Core/PluginManager.h (original) > +++ lldb/trunk/include/lldb/Core/PluginManager.h Fri Oct 10 18:43:03 2014 > @@ -361,6 +361,28 @@ public: > GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name); > > //------------------------------------------------------------------ > + // InstrumentationRuntime > + //------------------------------------------------------------------ > + static bool > + RegisterPlugin (const ConstString &name, > + const char *description, > + InstrumentationRuntimeCreateInstance create_callback, > + InstrumentationRuntimeGetType get_type_callback); > + > + static bool > + UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback); > + > + static InstrumentationRuntimeGetType > + GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx); > + > + static InstrumentationRuntimeCreateInstance > + GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx); > + > + static InstrumentationRuntimeCreateInstance > + GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString > &name); > + > + > + //------------------------------------------------------------------ > // Some plug-ins might register a DebuggerInitializeCallback > // callback when registering the plug-in. After a new Debugger > // instance is created, this DebuggerInitialize function will get > > Added: lldb/trunk/include/lldb/Target/InstrumentationRuntime.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/InstrumentationRuntime.h?rev=219546&view=auto > ============================================================================== > --- lldb/trunk/include/lldb/Target/InstrumentationRuntime.h (added) > +++ lldb/trunk/include/lldb/Target/InstrumentationRuntime.h Fri Oct 10 > 18:43:03 2014 > @@ -0,0 +1,47 @@ > +//===-- InstrumentationRuntime.h --------------------------------*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef liblldb_InstrumentationRuntime_h_ > +#define liblldb_InstrumentationRuntime_h_ > + > +// C Includes > +// C++ Includes > +#include <vector> > +#include <map> > + > +// Other libraries and framework includes > +// Project includes > +#include "lldb/lldb-private.h" > +#include "lldb/lldb-types.h" > +#include "lldb/Core/PluginInterface.h" > + > +namespace lldb_private { > + > +typedef std::map<lldb::InstrumentationRuntimeType, > lldb::InstrumentationRuntimeSP> InstrumentationRuntimeCollection; > + > +class InstrumentationRuntime : > + public std::enable_shared_from_this<InstrumentationRuntime>, > + public PluginInterface > +{ > +public: > + > + static void > + ModulesDidLoad(lldb_private::ModuleList &module_list, Process *process, > InstrumentationRuntimeCollection &runtimes); > + > + virtual void > + ModulesDidLoad(lldb_private::ModuleList &module_list); > + > + virtual bool > + IsActive(); > + > +}; > + > +} // namespace lldb_private > + > +#endif // liblldb_InstrumentationRuntime_h_ > > Added: lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h?rev=219546&view=auto > ============================================================================== > --- lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h (added) > +++ lldb/trunk/include/lldb/Target/InstrumentationRuntimeStopInfo.h Fri Oct > 10 18:43:03 2014 > @@ -0,0 +1,52 @@ > +//===-- InstrumentationRuntimeStopInfo.h ------------------------*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef liblldb_InstrumentationRuntimeStopInfo_h_ > +#define liblldb_InstrumentationRuntimeStopInfo_h_ > + > +// C Includes > +// C++ Includes > +#include <string> > + > +// Other libraries and framework includes > +// Project includes > +#include "lldb/Target/StopInfo.h" > +#include "lldb/Core/StructuredData.h" > + > +namespace lldb_private { > + > +class InstrumentationRuntimeStopInfo : public StopInfo > +{ > +public: > + > + virtual ~InstrumentationRuntimeStopInfo() > + { > + } > + > + virtual lldb::StopReason > + GetStopReason () const > + { > + return lldb::eStopReasonInstrumentation; > + } > + > + virtual const char * > + GetDescription (); > + > + static lldb::StopInfoSP > + CreateStopReasonWithInstrumentationData (Thread &thread, std::string > description, StructuredData::ObjectSP additional_data); > + > +private: > + > + InstrumentationRuntimeStopInfo(Thread &thread, std::string description, > StructuredData::ObjectSP additional_data); > + > +}; > + > +} // namespace lldb_private > + > +#endif // liblldb_InstrumentationRuntimeStopInfo_h_ > > Modified: lldb/trunk/include/lldb/Target/Process.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/Target/Process.h (original) > +++ lldb/trunk/include/lldb/Target/Process.h Fri Oct 10 18:43:03 2014 > @@ -52,6 +52,7 @@ > #include "lldb/Target/ThreadList.h" > #include "lldb/Target/UnixSignals.h" > #include "lldb/Utility/PseudoTerminal.h" > +#include "lldb/Target/InstrumentationRuntime.h" > > namespace lldb_private { > > @@ -3082,6 +3083,7 @@ protected: > AllocatedMemoryCache m_allocated_memory_cache; > bool m_should_detach; /// Should we detach if > the process object goes away with an explicit call to Kill or Detach? > LanguageRuntimeCollection m_language_runtimes; > + InstrumentationRuntimeCollection m_instrumentation_runtimes; > std::unique_ptr<NextEventAction> m_next_event_action_ap; > std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions; > ProcessRunLock m_public_run_lock; > > Modified: lldb/trunk/include/lldb/Target/StopInfo.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StopInfo.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/Target/StopInfo.h (original) > +++ lldb/trunk/include/lldb/Target/StopInfo.h Fri Oct 10 18:43:03 2014 > @@ -18,6 +18,7 @@ > // Project includes > #include "lldb/lldb-public.h" > #include "lldb/Target/Process.h" > +#include "lldb/Core/StructuredData.h" > > namespace lldb_private { > > @@ -140,6 +141,12 @@ public: > return m_override_should_stop == eLazyBoolYes; > } > > + StructuredData::ObjectSP > + GetExtendedInfo () > + { > + return m_extended_info; > + } > + > static lldb::StopInfoSP > CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t > break_id); > > @@ -211,6 +218,8 @@ protected: > LazyBool m_override_should_notify; > LazyBool m_override_should_stop; > > + StructuredData::ObjectSP m_extended_info; // The extended info for this > stop info > + > // This determines whether the target has run since this stop info. > // N.B. running to evaluate a user expression does not count. > bool HasTargetRunSinceMe (); > > Modified: lldb/trunk/include/lldb/Target/Thread.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/Target/Thread.h (original) > +++ lldb/trunk/include/lldb/Target/Thread.h Fri Oct 10 18:43:03 2014 > @@ -535,7 +535,7 @@ public: > DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx); > > bool > - GetDescription (Stream &s, lldb::DescriptionLevel level, bool > json_output); > + GetDescription (Stream &s, lldb::DescriptionLevel level, bool > print_json_thread, bool print_json_stopinfo); > > //------------------------------------------------------------------ > /// Default implementation for stepping into. > > Modified: lldb/trunk/include/lldb/lldb-enumerations.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/lldb-enumerations.h (original) > +++ lldb/trunk/include/lldb/lldb-enumerations.h Fri Oct 10 18:43:03 2014 > @@ -185,7 +185,8 @@ namespace lldb { > eStopReasonException, > eStopReasonExec, // Program was re-exec'ed > eStopReasonPlanComplete, > - eStopReasonThreadExiting > + eStopReasonThreadExiting, > + eStopReasonInstrumentation > } StopReason; > > //---------------------------------------------------------------------- > @@ -387,6 +388,11 @@ namespace lldb { > eLanguageTypeDylan = 0x0020, ///< Dylan. > eNumLanguageTypes > } LanguageType; > + > + typedef enum InstrumentationRuntimeType { > + eInstrumentationRuntimeTypeAddressSanitizer = 0x0000, > + eNumInstrumentationRuntimeTypes > + } InstrumentationRuntimeType; > > typedef enum DynamicValueType > { > > Modified: lldb/trunk/include/lldb/lldb-forward.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/lldb-forward.h (original) > +++ lldb/trunk/include/lldb/lldb-forward.h Fri Oct 10 18:43:03 2014 > @@ -104,6 +104,7 @@ class FunctionInfo; > class InlineFunctionInfo; > class Instruction; > class InstructionList; > +class InstrumentationRuntime; > class IOHandler; > class IOObject; > class IRExecutionUnit; > @@ -312,6 +313,7 @@ namespace lldb { > typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP; > typedef std::shared_ptr<lldb_private::InlineFunctionInfo> > InlineFunctionInfoSP; > typedef std::shared_ptr<lldb_private::Instruction> InstructionSP; > + typedef std::shared_ptr<lldb_private::InstrumentationRuntime> > InstrumentationRuntimeSP; > typedef std::shared_ptr<lldb_private::IOHandler> IOHandlerSP; > typedef std::shared_ptr<lldb_private::IOObject> IOObjectSP; > typedef std::shared_ptr<lldb_private::JITLoader> JITLoaderSP; > > Modified: lldb/trunk/include/lldb/lldb-private-interfaces.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-interfaces.h?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/include/lldb/lldb-private-interfaces.h (original) > +++ lldb/trunk/include/lldb/lldb-private-interfaces.h Fri Oct 10 18:43:03 2014 > @@ -40,6 +40,8 @@ namespace lldb_private > typedef lldb::ThreadPlanSP (*ThreadPlanStepFromHereCallback) (ThreadPlan > *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); > typedef UnwindAssembly* (*UnwindAssemblyCreateInstance) (const ArchSpec > &arch); > typedef lldb::MemoryHistorySP (*MemoryHistoryCreateInstance) (const > lldb::ProcessSP &process_sp); > + typedef lldb::InstrumentationRuntimeType > (*InstrumentationRuntimeGetType) (); > + typedef lldb::InstrumentationRuntimeSP > (*InstrumentationRuntimeCreateInstance) (const lldb::ProcessSP &process_sp); > typedef int (*ComparisonFunction)(const void *, const void *); > typedef void (*DebuggerInitializeCallback)(Debugger &debugger); > > > Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) > +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Oct 10 18:43:03 2014 > @@ -637,6 +637,9 @@ > 8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources > */ = {isa = PBXBuildFile; fileRef = 8CCB017A19BA283D0009FD44 /* > ThreadCollection.cpp */; }; > 8CCB018219BA4E270009FD44 /* SBThreadCollection.h in Headers > */ = {isa = PBXBuildFile; fileRef = 8CCB018119BA4E210009FD44 /* > SBThreadCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; > 8CCB018319BA51BF0009FD44 /* SBThreadCollection.cpp in Sources > */ = {isa = PBXBuildFile; fileRef = 8CCB017F19BA4DD00009FD44 /* > SBThreadCollection.cpp */; }; > + 8CF02AE919DCC01900B14BE0 /* InstrumentationRuntime.cpp in > Sources */ = {isa = PBXBuildFile; fileRef = 8CF02ADF19DCBF3B00B14BE0 /* > InstrumentationRuntime.cpp */; }; > + 8CF02AEA19DCC02100B14BE0 /* AddressSanitizerRuntime.cpp in > Sources */ = {isa = PBXBuildFile; fileRef = 8CF02AE519DCBF8400B14BE0 /* > AddressSanitizerRuntime.cpp */; }; > + 8CF02AEF19DD16B100B14BE0 /* > InstrumentationRuntimeStopInfo.cpp in Sources */ = {isa = PBXBuildFile; > fileRef = 8CF02AED19DD15CF00B14BE0 /* InstrumentationRuntimeStopInfo.cpp */; > }; > 94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */ > = {isa = PBXBuildFile; fileRef = 94094C69163B6CD90083A547 /* > ValueObjectCast.cpp */; }; > 940B02F619DC96E700AD0F52 /* SBExecutionContext.cpp in Sources > */ = {isa = PBXBuildFile; fileRef = 940B02F519DC96E700AD0F52 /* > SBExecutionContext.cpp */; }; > 94145431175E63B500284436 /* lldb-versioning.h in Headers */ = > {isa = PBXBuildFile; fileRef = 94145430175D7FDE00284436 /* lldb-versioning.h > */; settings = {ATTRIBUTES = (Public, ); }; }; > @@ -1965,6 +1968,12 @@ > 8CCB017F19BA4DD00009FD44 /* SBThreadCollection.cpp */ = {isa > = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = > SBThreadCollection.cpp; path = source/API/SBThreadCollection.cpp; sourceTree > = "<group>"; }; > 8CCB018119BA4E210009FD44 /* SBThreadCollection.h */ = {isa = > PBXFileReference; lastKnownFileType = sourcecode.c.h; name = > SBThreadCollection.h; path = include/lldb/API/SBThreadCollection.h; > sourceTree = "<group>"; }; > 8CCB018419BA54930009FD44 /* SBThreadCollection.i */ = {isa = > PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = > SBThreadCollection.i; sourceTree = "<group>"; }; > + 8CF02ADF19DCBF3B00B14BE0 /* InstrumentationRuntime.cpp */ = > {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = > InstrumentationRuntime.cpp; path = source/Target/InstrumentationRuntime.cpp; > sourceTree = "<group>"; }; > + 8CF02AE019DCBF3B00B14BE0 /* InstrumentationRuntime.h */ = > {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = > InstrumentationRuntime.h; path = > include/lldb/Target/InstrumentationRuntime.h; sourceTree = "<group>"; }; > + 8CF02AE519DCBF8400B14BE0 /* AddressSanitizerRuntime.cpp */ = > {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = > sourcecode.cpp.cpp; path = AddressSanitizerRuntime.cpp; sourceTree = > "<group>"; }; > + 8CF02AE619DCBF8400B14BE0 /* AddressSanitizerRuntime.h */ = > {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = > sourcecode.c.h; path = AddressSanitizerRuntime.h; sourceTree = "<group>"; }; > + 8CF02AED19DD15CF00B14BE0 /* > InstrumentationRuntimeStopInfo.cpp */ = {isa = PBXFileReference; > lastKnownFileType = sourcecode.cpp.cpp; name = > InstrumentationRuntimeStopInfo.cpp; path = > source/Target/InstrumentationRuntimeStopInfo.cpp; sourceTree = "<group>"; }; > + 8CF02AEE19DD15CF00B14BE0 /* InstrumentationRuntimeStopInfo.h > */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = > InstrumentationRuntimeStopInfo.h; path = > include/lldb/Target/InstrumentationRuntimeStopInfo.h; sourceTree = "<group>"; > }; > 94005E0313F438DF001EF42D /* python-wrapper.swig */ = {isa = > PBXFileReference; lastKnownFileType = text; path = "python-wrapper.swig"; > sourceTree = "<group>"; }; > 94005E0513F45A1B001EF42D /* embedded_interpreter.py */ = {isa > = PBXFileReference; lastKnownFileType = text.script.python; name = > embedded_interpreter.py; path = source/Interpreter/embedded_interpreter.py; > sourceTree = "<group>"; }; > 94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = > PBXFileReference; lastKnownFileType = sourcecode.c.h; name = > PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; > sourceTree = "<group>"; }; > @@ -2423,6 +2432,7 @@ > 260C897110F57C5600BB2B04 /* Plugins */ = { > isa = PBXGroup; > children = ( > + 8CF02ADD19DCBEC200B14BE0 /* > InstrumentationRuntime */, > 8C2D6A58197A1FB9006989C9 /* MemoryHistory */, > 26DB3E051379E7AD0080DC73 /* ABI */, > 260C897210F57C5600BB2B04 /* Disassembler */, > @@ -3746,6 +3756,10 @@ > 26BC7DEF10F1B80200F91463 /* Target */ = { > isa = PBXGroup; > children = ( > + 8CF02AE019DCBF3B00B14BE0 /* > InstrumentationRuntime.h */, > + 8CF02ADF19DCBF3B00B14BE0 /* > InstrumentationRuntime.cpp */, > + 8CF02AEE19DD15CF00B14BE0 /* > InstrumentationRuntimeStopInfo.h */, > + 8CF02AED19DD15CF00B14BE0 /* > InstrumentationRuntimeStopInfo.cpp */, > 3FDFD6C3199C396E009756A7 /* FileAction.h */, > 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */, > 23EDE3311926843600F6A132 /* > NativeRegisterContext.h */, > @@ -4264,6 +4278,23 @@ > path = asan; > sourceTree = "<group>"; > }; > + 8CF02ADD19DCBEC200B14BE0 /* InstrumentationRuntime */ = { > + isa = PBXGroup; > + children = ( > + 8CF02ADE19DCBEE600B14BE0 /* AddressSanitizer > */, > + ); > + path = InstrumentationRuntime; > + sourceTree = "<group>"; > + }; > + 8CF02ADE19DCBEE600B14BE0 /* AddressSanitizer */ = { > + isa = PBXGroup; > + children = ( > + 8CF02AE519DCBF8400B14BE0 /* > AddressSanitizerRuntime.cpp */, > + 8CF02AE619DCBF8400B14BE0 /* > AddressSanitizerRuntime.h */, > + ); > + path = AddressSanitizer; > + sourceTree = "<group>"; > + }; > 9457596415349416005A9070 /* POSIX */ = { > isa = PBXGroup; > children = ( > @@ -4965,6 +4996,7 @@ > 2689000713353DB600698AC0 /* > BreakpointSite.cpp in Sources */, > 2689000913353DB600698AC0 /* > BreakpointSiteList.cpp in Sources */, > 26474CC918D0CB5B0073DEBA /* > RegisterContextMemory.cpp in Sources */, > + 8CF02AEA19DCC02100B14BE0 /* > AddressSanitizerRuntime.cpp in Sources */, > 26474CB218D0CB180073DEBA /* > RegisterContextLinux_i386.cpp in Sources */, > 26474CCB18D0CB5B0073DEBA /* > RegisterContextPOSIX_mips64.cpp in Sources */, > 2689000B13353DB600698AC0 /* Stoppoint.cpp in > Sources */, > @@ -5002,6 +5034,7 @@ > 2689002813353DDE00698AC0 /* > CommandObjectThread.cpp in Sources */, > 2689002913353DDE00698AC0 /* > CommandObjectVersion.cpp in Sources */, > 2689002A13353E0400698AC0 /* Address.cpp in > Sources */, > + 8CF02AE919DCC01900B14BE0 /* > InstrumentationRuntime.cpp in Sources */, > 2689002B13353E0400698AC0 /* AddressRange.cpp > in Sources */, > 236124A41986B4E2004EFC37 /* IOObject.cpp in > Sources */, > 2689002C13353E0400698AC0 /* > AddressResolver.cpp in Sources */, > @@ -5223,6 +5256,7 @@ > 268900FA13353E6F00698AC0 /* ThreadList.cpp in > Sources */, > 268900FB13353E6F00698AC0 /* ThreadPlan.cpp in > Sources */, > 232CB619191E00CD00EF39FC /* > NativeProcessProtocol.cpp in Sources */, > + 8CF02AEF19DD16B100B14BE0 /* > InstrumentationRuntimeStopInfo.cpp in Sources */, > 268900FC13353E6F00698AC0 /* > ThreadPlanBase.cpp in Sources */, > 268900FD13353E6F00698AC0 /* > ThreadPlanCallFunction.cpp in Sources */, > 268900FE13353E6F00698AC0 /* > ThreadPlanCallUserExpression.cpp in Sources */, > > Modified: lldb/trunk/scripts/Python/interface/SBThread.i > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBThread.i?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/scripts/Python/interface/SBThread.i (original) > +++ lldb/trunk/scripts/Python/interface/SBThread.i Fri Oct 10 18:43:03 2014 > @@ -110,6 +110,14 @@ public: > ") GetStopReasonDataAtIndex; > uint64_t > GetStopReasonDataAtIndex(uint32_t idx); > + > + %feature("autodoc", " > + Collects a thread's stop reason extended information dictionary and > prints it > + into the SBStream in a JSON format. The format of this JSON dictionary > depends > + on the stop reason and is currently used only for instrumentation > plugins. > + ") GetStopReasonExtendedInfoAsJSON; > + bool > + GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream); > > %feature("autodoc", " > Pass only an (int)length and expect to get a Python string describing the > > Modified: lldb/trunk/source/API/SBThread.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/API/SBThread.cpp (original) > +++ lldb/trunk/source/API/SBThread.cpp Fri Oct 10 18:43:03 2014 > @@ -195,6 +195,7 @@ SBThread::GetStopReasonDataCount () > case eStopReasonExec: > case eStopReasonPlanComplete: > case eStopReasonThreadExiting: > + case eStopReasonInstrumentation: > // There is no data for these stop reasons. > return 0; > > @@ -255,6 +256,7 @@ SBThread::GetStopReasonDataAtIndex (uint > case eStopReasonExec: > case eStopReasonPlanComplete: > case eStopReasonThreadExiting: > + case eStopReasonInstrumentation: > // There is no data for these stop reasons. > return 0; > > @@ -306,6 +308,26 @@ SBThread::GetStopReasonDataAtIndex (uint > return 0; > } > > +bool > +SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream) > +{ > + Stream &strm = stream.ref(); > + > + ExecutionContext exe_ctx (m_opaque_sp.get()); > + if (! exe_ctx.HasThreadScope()) > + return false; > + > + > + StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); > + StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); > + if (! info) > + return false; > + > + info->Dump(strm); > + > + return true; > +} > + > size_t > SBThread::GetStopDescription (char *dst, size_t dst_len) > { > > Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) > +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Fri Oct 10 18:43:03 > 2014 > @@ -1431,7 +1431,8 @@ public: > void > OptionParsingStarting () > { > - m_json = false; > + m_json_thread = false; > + m_json_stopinfo = false; > } > > virtual > @@ -1448,10 +1449,14 @@ public: > switch (short_option) > { > case 'j': > - m_json = true; > + m_json_thread = true; > + break; > + > + case 's': > + m_json_stopinfo = true; > break; > > - default: > + default: > return Error("invalid short option character '%c'", > short_option); > > } > @@ -1464,7 +1469,8 @@ public: > return g_option_table; > } > > - bool m_json; > + bool m_json_thread; > + bool m_json_stopinfo; > > static OptionDefinition g_option_table[]; > }; > @@ -1486,7 +1492,7 @@ public: > HandleOneThread (Thread &thread, CommandReturnObject &result) > { > Stream &strm = result.GetOutputStream(); > - if (!thread.GetDescription (strm, eDescriptionLevelFull, > m_options.m_json)) > + if (!thread.GetDescription (strm, eDescriptionLevelFull, > m_options.m_json_thread, m_options.m_json_stopinfo)) > { > result.AppendErrorWithFormat ("error displaying info for thread: > \"%d\"\n", thread.GetIndexID()); > result.SetStatus (eReturnStatusFailed); > @@ -1503,6 +1509,7 @@ OptionDefinition > CommandObjectThreadInfo::CommandOptions::g_option_table[] = > { > { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, > NULL, 0, eArgTypeNone, "Display the thread info in JSON format."}, > + { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, > NULL, NULL, 0, eArgTypeNone, "Display the extended stop info in JSON > format."}, > > { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } > }; > > Modified: lldb/trunk/source/Core/Debugger.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/Core/Debugger.cpp (original) > +++ lldb/trunk/source/Core/Debugger.cpp Fri Oct 10 18:43:03 2014 > @@ -3234,6 +3234,7 @@ Debugger::HandleProcessEvent (const Even > case eStopReasonException: > case eStopReasonExec: > case eStopReasonThreadExiting: > + case eStopReasonInstrumentation: > if (!other_thread) > other_thread = thread; > break; > > Modified: lldb/trunk/source/Core/PluginManager.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/PluginManager.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/Core/PluginManager.cpp (original) > +++ lldb/trunk/source/Core/PluginManager.cpp Fri Oct 10 18:43:03 2014 > @@ -2172,6 +2172,125 @@ PluginManager::GetMemoryHistoryCreateCal > return NULL; > } > > +#pragma mark InstrumentationRuntime > + > +struct InstrumentationRuntimeInstance > +{ > + InstrumentationRuntimeInstance() : > + name(), > + description(), > + create_callback(NULL) > + { > + } > + > + ConstString name; > + std::string description; > + InstrumentationRuntimeCreateInstance create_callback; > + InstrumentationRuntimeGetType get_type_callback; > +}; > + > +typedef std::vector<InstrumentationRuntimeInstance> > InstrumentationRuntimeInstances; > + > +static Mutex & > +GetInstrumentationRuntimeMutex () > +{ > + static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); > + return g_instances_mutex; > +} > + > +static InstrumentationRuntimeInstances & > +GetInstrumentationRuntimeInstances () > +{ > + static InstrumentationRuntimeInstances g_instances; > + return g_instances; > +} > + > +bool > +PluginManager::RegisterPlugin > +( > + const ConstString &name, > + const char *description, > + InstrumentationRuntimeCreateInstance create_callback, > + InstrumentationRuntimeGetType get_type_callback > + ) > +{ > + if (create_callback) > + { > + InstrumentationRuntimeInstance instance; > + assert ((bool)name); > + instance.name = name; > + if (description && description[0]) > + instance.description = description; > + instance.create_callback = create_callback; > + instance.get_type_callback = get_type_callback; > + Mutex::Locker locker (GetInstrumentationRuntimeMutex ()); > + GetInstrumentationRuntimeInstances ().push_back (instance); > + } > + return false; > +} > + > +bool > +PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance > create_callback) > +{ > + if (create_callback) > + { > + Mutex::Locker locker (GetInstrumentationRuntimeMutex ()); > + InstrumentationRuntimeInstances &instances = > GetInstrumentationRuntimeInstances (); > + > + InstrumentationRuntimeInstances::iterator pos, end = instances.end(); > + for (pos = instances.begin(); pos != end; ++ pos) > + { > + if (pos->create_callback == create_callback) > + { > + instances.erase(pos); > + return true; > + } > + } > + } > + return false; > +} > + > +InstrumentationRuntimeGetType > +PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx) > +{ > + Mutex::Locker locker (GetInstrumentationRuntimeMutex ()); > + InstrumentationRuntimeInstances &instances = > GetInstrumentationRuntimeInstances (); > + if (idx < instances.size()) > + return instances[idx].get_type_callback; > + return NULL; > +} > + > +InstrumentationRuntimeCreateInstance > +PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx) > +{ > + Mutex::Locker locker (GetInstrumentationRuntimeMutex ()); > + InstrumentationRuntimeInstances &instances = > GetInstrumentationRuntimeInstances (); > + if (idx < instances.size()) > + return instances[idx].create_callback; > + return NULL; > +} > + > + > +InstrumentationRuntimeCreateInstance > +PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const > ConstString &name) > +{ > + if (name) > + { > + Mutex::Locker locker (GetInstrumentationRuntimeMutex ()); > + InstrumentationRuntimeInstances &instances = > GetInstrumentationRuntimeInstances (); > + > + InstrumentationRuntimeInstances::iterator pos, end = instances.end(); > + for (pos = instances.begin(); pos != end; ++ pos) > + { > + if (name == pos->name) > + return pos->create_callback; > + } > + } > + return NULL; > +} > + > +#pragma mark PluginManager > + > void > PluginManager::DebuggerInitialize (Debugger &debugger) > { > > Added: > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp?rev=219546&view=auto > ============================================================================== > --- > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp > (added) > +++ > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp > Fri Oct 10 18:43:03 2014 > @@ -0,0 +1,300 @@ > +//===-- AddressSanitizerRuntime.cpp -----------------------------*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "AddressSanitizerRuntime.h" > + > +#include "lldb/Core/PluginInterface.h" > +#include "lldb/Core/PluginManager.h" > +#include "lldb/Core/ModuleList.h" > +#include "lldb/Symbol/SymbolContext.h" > +#include "lldb/Core/Module.h" > +#include "lldb/Target/Target.h" > +#include "lldb/Target/Thread.h" > +#include "lldb/Target/StopInfo.h" > +#include "lldb/Symbol/Symbol.h" > +#include "lldb/Breakpoint/StoppointCallbackContext.h" > +#include "lldb/Core/ValueObject.h" > +#include "lldb/Target/InstrumentationRuntimeStopInfo.h" > +#include "lldb/Core/Debugger.h" > +#include "lldb/Core/Stream.h" > +#include "lldb/Core/StreamFile.h" > + > +using namespace lldb; > +using namespace lldb_private; > + > +lldb::InstrumentationRuntimeSP > +AddressSanitizerRuntime::CreateInstance (const lldb::ProcessSP &process_sp) > +{ > + return InstrumentationRuntimeSP(new AddressSanitizerRuntime(process_sp)); > +} > + > +void > +AddressSanitizerRuntime::Initialize() > +{ > + PluginManager::RegisterPlugin (GetPluginNameStatic(), > + "AddressSanitizer instrumentation runtime > plugin.", > + CreateInstance, > + GetTypeStatic); > +} > + > +void > +AddressSanitizerRuntime::Terminate() > +{ > + PluginManager::UnregisterPlugin (CreateInstance); > +} > + > +lldb_private::ConstString > +AddressSanitizerRuntime::GetPluginNameStatic() > +{ > + return ConstString("AddressSanitizer"); > +} > + > +lldb::InstrumentationRuntimeType > +AddressSanitizerRuntime::GetTypeStatic() > +{ > + return eInstrumentationRuntimeTypeAddressSanitizer; > +} > + > +AddressSanitizerRuntime::AddressSanitizerRuntime(const ProcessSP > &process_sp) : > + m_is_active(false), > + m_runtime_module(), > + m_process(process_sp), > + m_breakpoint_id(0) > +{ > +} > + > +AddressSanitizerRuntime::~AddressSanitizerRuntime() > +{ > + Deactivate(); > +} > + > +bool ModuleContainsASanRuntime(Module * module) > +{ > + SymbolContextList sc_list; > + const bool include_symbols = true; > + const bool append = true; > + const bool include_inlines = true; > + > + size_t num_matches = > module->FindFunctions(ConstString("__asan_get_alloc_stack"), NULL, > eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list); > + > + return num_matches > 0; > +} > + > +void > +AddressSanitizerRuntime::ModulesDidLoad(lldb_private::ModuleList > &module_list) > +{ > + if (IsActive()) > + return; > + > + if (m_runtime_module) { > + Activate(); > + return; > + } > + > + Mutex::Locker modules_locker(module_list.GetMutex()); > + const size_t num_modules = module_list.GetSize(); > + for (size_t i = 0; i < num_modules; ++i) > + { > + Module *module_pointer = > module_list.GetModulePointerAtIndexUnlocked(i); > + const FileSpec & file_spec = module_pointer->GetFileSpec(); > + if (! file_spec) > + continue; > + > + static RegularExpression > g_asan_runtime_regex("libclang_rt.asan_(.*)_dynamic\\.dylib"); > + if (g_asan_runtime_regex.Execute > (file_spec.GetFilename().GetCString()) || module_pointer->IsExecutable()) > + { > + if (ModuleContainsASanRuntime(module_pointer)) > + { > + m_runtime_module = module_pointer->shared_from_this(); > + Activate(); > + return; > + } > + } > + } > +} > + > +bool > +AddressSanitizerRuntime::IsActive() > +{ > + return m_is_active; > +} > + > +#define RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC 2*1000*1000 > + > +const char * > +address_sanitizer_retrieve_report_data_command = R"( > + struct { > + int present; > + void *pc, *bp, *sp, *address; > + int access_type; > + size_t access_size; > + const char *description; > + } t; > + > + t.present = ((int (*) ())__asan_report_present)(); > + t.pc = ((void * (*) ())__asan_get_report_pc)(); > + /* commented out because rdar://problem/18533301 > + t.bp = ((void * (*) ())__asan_get_report_bp)(); > + t.sp = ((void * (*) ())__asan_get_report_sp)(); > + */ > + t.address = ((void * (*) ())__asan_get_report_address)(); > + t.description = ((const char * (*) ())__asan_get_report_description)(); > + t.access_type = ((int (*) ())__asan_get_report_access_type)(); > + t.access_size = ((size_t (*) ())__asan_get_report_access_size)(); > + > + t; > +)"; > + > +StructuredData::ObjectSP > +AddressSanitizerRuntime::RetrieveReportData() > +{ > + ThreadSP thread_sp = m_process->GetThreadList().GetSelectedThread(); > + StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); > + > + if (!frame_sp) > + return StructuredData::ObjectSP(); > + > + EvaluateExpressionOptions options; > + options.SetUnwindOnError(true); > + options.SetTryAllThreads(true); > + options.SetStopOthers(true); > + options.SetIgnoreBreakpoints(true); > + options.SetTimeoutUsec(RETRIEVE_REPORT_DATA_FUNCTION_TIMEOUT_USEC); > + > + ValueObjectSP return_value_sp; > + if > (m_process->GetTarget().EvaluateExpression(address_sanitizer_retrieve_report_data_command, > frame_sp.get(), return_value_sp, options) != eExpressionCompleted) > + return StructuredData::ObjectSP(); > + > + int present = > return_value_sp->GetValueForExpressionPath(".present")->GetValueAsUnsigned(0); > + if (present != 1) > + return StructuredData::ObjectSP(); > + > + addr_t pc = > return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0); > + addr_t bp = > return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0); > + addr_t sp = > return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0); > + addr_t address = > return_value_sp->GetValueForExpressionPath(".address")->GetValueAsUnsigned(0); > + addr_t access_type = > return_value_sp->GetValueForExpressionPath(".access_type")->GetValueAsUnsigned(0); > + addr_t access_size = > return_value_sp->GetValueForExpressionPath(".access_size")->GetValueAsUnsigned(0); > + addr_t description_ptr = > return_value_sp->GetValueForExpressionPath(".description")->GetValueAsUnsigned(0); > + std::string description; > + Error error; > + m_process->ReadCStringFromMemory(description_ptr, description, error); > + > + StructuredData::Dictionary *dict = new StructuredData::Dictionary(); > + dict->AddStringItem("instrumentation_class", "AddressSanitizer"); > + dict->AddStringItem("stop_type", "fatal_error"); > + dict->AddIntegerItem("pc", pc); > + dict->AddIntegerItem("bp", bp); > + dict->AddIntegerItem("sp", sp); > + dict->AddIntegerItem("address", address); > + dict->AddIntegerItem("access_type", access_type); > + dict->AddIntegerItem("access_size", access_size); > + dict->AddStringItem("description", description); > + > + return StructuredData::ObjectSP(dict); > +} > + > +std::string > +AddressSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report) > +{ > + std::string description = > report->GetAsDictionary()->GetValueForKey("description")->GetAsString()->GetValue(); > + if (description == "heap-use-after-free") { > + return "Use of deallocated memory detected"; > + } else if (description == "heap-buffer-overflow") { > + return "Heap buffer overflow detected"; > + } else if (description == "stack-buffer-underflow") { > + return "Stack buffer underflow detected"; > + } else if (description == "initialization-order-fiasco") { > + return "Initialization order problem detected"; > + } else if (description == "stack-buffer-overflow") { > + return "Stack buffer overflow detected"; > + } else if (description == "stack-use-after-return") { > + return "Use of returned stack memory detected"; > + } else if (description == "use-after-poison") { > + return "Use of poisoned memory detected"; > + } else if (description == "container-overflow") { > + return "Container overflow detected"; > + } else if (description == "stack-use-after-scope") { > + return "Use of out-of-scope stack memory detected"; > + } else if (description == "global-buffer-overflow") { > + return "Global buffer overflow detected"; > + } else if (description == "unknown-crash") { > + return "Invalid memory access detected"; > + } > + > + // for unknown report codes just show the code > + return description; > +} > + > +bool > +AddressSanitizerRuntime::NotifyBreakpointHit(void *baton, > StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id) > +{ > + assert (baton && "null baton"); > + if (!baton) > + return false; > + > + AddressSanitizerRuntime *const instance = > static_cast<AddressSanitizerRuntime*>(baton); > + > + StructuredData::ObjectSP report = instance->RetrieveReportData(); > + std::string description; > + if (report) { > + description = instance->FormatDescription(report); > + } > + ThreadSP thread = context->exe_ctx_ref.GetThreadSP(); > + > thread->SetStopInfo(InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(*thread, > description.c_str(), report)); > + > + instance->m_runtime_module->ReportWarning("AddressSanitizer report > breakpoint hit. Use 'thread info -s' to get extended information about the > report.\n"); > + > + // Return true to stop the target, false to just let the target run. > + return true; > +} > + > +void > +AddressSanitizerRuntime::Activate() > +{ > + if (m_is_active) > + return; > + > + ConstString symbol_name ("__asan::AsanDie()"); > + const Symbol *symbol = m_runtime_module->FindFirstSymbolWithNameAndType > (symbol_name, eSymbolTypeCode); > + > + if (symbol == NULL) > + return; > + > + if (!symbol->GetAddress().IsValid()) > + return; > + > + Target &target = m_process->GetTarget(); > + addr_t symbol_address = > symbol->GetAddress().GetOpcodeLoadAddress(&target); > + > + if (symbol_address == LLDB_INVALID_ADDRESS) > + return; > + > + bool internal = true; > + bool hardware = false; > + Breakpoint *breakpoint = > m_process->GetTarget().CreateBreakpoint(symbol_address, internal, > hardware).get(); > + breakpoint->SetCallback (AddressSanitizerRuntime::NotifyBreakpointHit, > this, true); > + breakpoint->SetBreakpointKind ("address-sanitizer-report"); > + m_breakpoint_id = breakpoint->GetID(); > + > + m_runtime_module->ReportWarning("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; > +} > + > +void > +AddressSanitizerRuntime::Deactivate() > +{ > + if (m_breakpoint_id != LLDB_INVALID_BREAK_ID) > + { > + m_process->GetTarget().RemoveBreakpointByID(m_breakpoint_id); > + m_breakpoint_id = LLDB_INVALID_BREAK_ID; > + } > + m_is_active = false; > +} > > Added: > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h?rev=219546&view=auto > ============================================================================== > --- > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h > (added) > +++ > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h > Fri Oct 10 18:43:03 2014 > @@ -0,0 +1,86 @@ > +//===-- AddressSanitizerRuntime.h -------------------------------*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef liblldb_AddressSanitizerRuntime_h_ > +#define liblldb_AddressSanitizerRuntime_h_ > + > +#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 { > + > +class AddressSanitizerRuntime : public lldb_private::InstrumentationRuntime > +{ > +public: > + > + static lldb::InstrumentationRuntimeSP > + CreateInstance (const lldb::ProcessSP &process_sp); > + > + static void > + Initialize(); > + > + static void > + Terminate(); > + > + static lldb_private::ConstString > + GetPluginNameStatic(); > + > + static lldb::InstrumentationRuntimeType > + GetTypeStatic(); > + > + virtual > + ~AddressSanitizerRuntime(); > + > + virtual lldb_private::ConstString > + GetPluginName() { return GetPluginNameStatic(); } > + > + virtual lldb::InstrumentationRuntimeType > + GetType() { return GetTypeStatic(); } > + > + virtual uint32_t > + GetPluginVersion() { return 1; } > + > + virtual void > + ModulesDidLoad(lldb_private::ModuleList &module_list); > + > + virtual bool > + IsActive(); > + > +private: > + > + AddressSanitizerRuntime(const lldb::ProcessSP &process_sp); > + > + void > + Activate(); > + > + void > + Deactivate(); > + > + static bool > + NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, > lldb::user_id_t break_id, lldb::user_id_t break_loc_id); > + > + StructuredData::ObjectSP > + RetrieveReportData(); > + > + std::string > + FormatDescription(StructuredData::ObjectSP report); > + > + bool m_is_active; > + lldb::ModuleSP m_runtime_module; > + lldb::ProcessSP m_process; > + lldb::user_id_t m_breakpoint_id; > + > +}; > + > +} // namespace lldb_private > + > +#endif // liblldb_InstrumentationRuntime_h_ > > Added: > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/CMakeLists.txt?rev=219546&view=auto > ============================================================================== > --- > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/CMakeLists.txt > (added) > +++ > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/CMakeLists.txt > Fri Oct 10 18:43:03 2014 > @@ -0,0 +1,5 @@ > +set(LLVM_NO_RTTI 1) > + > +add_lldb_library(lldbPluginInstrumentationRuntimeAddressSanitizer > + AddressSanitizerRuntime.cpp > + ) > > Added: > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile?rev=219546&view=auto > ============================================================================== > --- > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile > (added) > +++ > lldb/trunk/source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile > Fri Oct 10 18:43:03 2014 > @@ -0,0 +1,14 @@ > +##===- source/Plugins/InstrumentationRuntime/AddressSanitizer Makefile > -*-===## > +# > +# The LLVM Compiler Infrastructure > +# > +# This file is distributed under the University of Illinois Open Source > +# License. See LICENSE.TXT for details. > +# > +##===----------------------------------------------------------------------===## > + > +LLDB_LEVEL := ../../../.. > +LIBRARYNAME := lldbPluginInstrumentationRuntimeAddressSanitizer > +BUILD_ARCHIVE = 1 > + > +include $(LLDB_LEVEL)/Makefile > > Added: lldb/trunk/source/Plugins/InstrumentationRuntime/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/CMakeLists.txt?rev=219546&view=auto > ============================================================================== > --- lldb/trunk/source/Plugins/InstrumentationRuntime/CMakeLists.txt (added) > +++ lldb/trunk/source/Plugins/InstrumentationRuntime/CMakeLists.txt Fri Oct > 10 18:43:03 2014 > @@ -0,0 +1 @@ > +add_subdirectory(AddressSanitizer) > > Modified: lldb/trunk/source/Target/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/CMakeLists.txt?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/Target/CMakeLists.txt (original) > +++ lldb/trunk/source/Target/CMakeLists.txt Fri Oct 10 18:43:03 2014 > @@ -9,6 +9,8 @@ add_lldb_library(lldbTarget > FileAction.cpp > JITLoader.cpp > JITLoaderList.cpp > + InstrumentationRuntime.cpp > + InstrumentationRuntimeStopInfo.cpp > LanguageRuntime.cpp > Memory.cpp > MemoryHistory.cpp > > Added: lldb/trunk/source/Target/InstrumentationRuntime.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/InstrumentationRuntime.cpp?rev=219546&view=auto > ============================================================================== > --- lldb/trunk/source/Target/InstrumentationRuntime.cpp (added) > +++ lldb/trunk/source/Target/InstrumentationRuntime.cpp Fri Oct 10 18:43:03 > 2014 > @@ -0,0 +1,48 @@ > +//===-- InstrumentationRuntime.cpp ------------------------------*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "lldb/lldb-private.h" > +#include "lldb/Target/Process.h" > +#include "lldb/Core/PluginManager.h" > +#include "lldb/Target/InstrumentationRuntime.h" > + > +using namespace lldb; > +using namespace lldb_private; > + > +void > +InstrumentationRuntime::ModulesDidLoad(lldb_private::ModuleList > &module_list, lldb_private::Process *process, > InstrumentationRuntimeCollection &runtimes) > +{ > + InstrumentationRuntimeCreateInstance create_callback = NULL; > + InstrumentationRuntimeGetType get_type_callback; > + for (uint32_t idx = 0; ; ++idx) > + { > + create_callback = > PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(idx); > + if (create_callback == NULL) > + break; > + get_type_callback = > PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(idx); > + InstrumentationRuntimeType type = get_type_callback(); > + > + InstrumentationRuntimeCollection::iterator pos; > + pos = runtimes.find (type); > + if (pos == runtimes.end()) { > + runtimes[type] = create_callback(process->shared_from_this()); > + } > + } > +} > + > +void > +InstrumentationRuntime::ModulesDidLoad(lldb_private::ModuleList &module_list) > +{ > +} > + > +bool > +InstrumentationRuntime::IsActive() > +{ > + return false; > +} > > Added: lldb/trunk/source/Target/InstrumentationRuntimeStopInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/InstrumentationRuntimeStopInfo.cpp?rev=219546&view=auto > ============================================================================== > --- lldb/trunk/source/Target/InstrumentationRuntimeStopInfo.cpp (added) > +++ lldb/trunk/source/Target/InstrumentationRuntimeStopInfo.cpp Fri Oct 10 > 18:43:03 2014 > @@ -0,0 +1,36 @@ > +//===-- InstrumentationRuntimeStopInfo.cpp ----------------------*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "lldb/Target/InstrumentationRuntimeStopInfo.h" > + > +#include "lldb/lldb-private.h" > +#include "lldb/Target/Process.h" > +#include "lldb/Target/InstrumentationRuntime.h" > + > +using namespace lldb; > +using namespace lldb_private; > + > +InstrumentationRuntimeStopInfo::InstrumentationRuntimeStopInfo(Thread > &thread, std::string description, StructuredData::ObjectSP additional_data) : > + StopInfo(thread, 0) > +{ > + m_extended_info = additional_data; > + m_description = description; > +} > + > +const char * > +InstrumentationRuntimeStopInfo::GetDescription () > +{ > + return m_description.c_str(); > +} > + > +StopInfoSP > +InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData > (Thread &thread, std::string description, StructuredData::ObjectSP > additionalData) > +{ > + return StopInfoSP(new InstrumentationRuntimeStopInfo(thread, > description, additionalData)); > +} > > Modified: lldb/trunk/source/Target/Process.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/Target/Process.cpp (original) > +++ lldb/trunk/source/Target/Process.cpp Fri Oct 10 18:43:03 2014 > @@ -48,6 +48,7 @@ > #include "lldb/Target/Thread.h" > #include "lldb/Target/ThreadPlan.h" > #include "lldb/Target/ThreadPlanBase.h" > +#include "lldb/Target/InstrumentationRuntime.h" > #include "Plugins/Process/Utility/InferiorCallPOSIX.h" > > using namespace lldb; > @@ -843,6 +844,7 @@ Process::Finalize() > m_memory_cache.Clear(); > m_allocated_memory_cache.Clear(); > m_language_runtimes.clear(); > + m_instrumentation_runtimes.clear(); > m_next_event_action_ap.reset(); > //#ifdef LLDB_CONFIGURATION_DEBUG > // StreamFile s(stdout, false); > @@ -5983,6 +5985,7 @@ Process::DidExec () > m_image_tokens.clear(); > m_allocated_memory_cache.Clear(); > m_language_runtimes.clear(); > + m_instrumentation_runtimes.clear(); > m_thread_list.DiscardThreadPlans(); > m_memory_cache.Clear(true); > DoDidExec(); > @@ -6033,13 +6036,24 @@ Process::ResolveIndirectFunction(const A > void > Process::ModulesDidLoad (ModuleList &module_list) > { > - SystemRuntime *sys_runtime = GetSystemRuntime(); > - if (sys_runtime) > - { > - sys_runtime->ModulesDidLoad (module_list); > - } > + SystemRuntime *sys_runtime = GetSystemRuntime(); > + if (sys_runtime) > + { > + sys_runtime->ModulesDidLoad (module_list); > + } > + > + GetJITLoaders().ModulesDidLoad (module_list); > + > + // Give runtimes a chance to be created. > + InstrumentationRuntime::ModulesDidLoad(module_list, this, > m_instrumentation_runtimes); > + > + // Tell runtimes about new modules. > + for (auto pos = m_instrumentation_runtimes.begin(); pos != > m_instrumentation_runtimes.end(); ++pos) > + { > + InstrumentationRuntimeSP runtime = pos->second; > + runtime->ModulesDidLoad(module_list); > + } > > - GetJITLoaders().ModulesDidLoad (module_list); > } > > ThreadCollectionSP > > Modified: lldb/trunk/source/Target/StopInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/Target/StopInfo.cpp (original) > +++ lldb/trunk/source/Target/StopInfo.cpp Fri Oct 10 18:43:03 2014 > @@ -40,7 +40,8 @@ StopInfo::StopInfo (Thread &thread, uint > m_resume_id (thread.GetProcess()->GetResumeID()), > m_value (value), > m_override_should_notify (eLazyBoolCalculate), > - m_override_should_stop (eLazyBoolCalculate) > + m_override_should_stop (eLazyBoolCalculate), > + m_extended_info() > { > } > > > Modified: lldb/trunk/source/Target/Thread.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/Target/Thread.cpp (original) > +++ lldb/trunk/source/Target/Thread.cpp Fri Oct 10 18:43:03 2014 > @@ -2086,6 +2086,7 @@ Thread::StopReasonAsCString (lldb::StopR > case eStopReasonExec: return "exec"; > case eStopReasonPlanComplete: return "plan complete"; > case eStopReasonThreadExiting: return "thread exiting"; > + case eStopReasonInstrumentation: return "instrumentation break"; > } > > > @@ -2165,17 +2166,28 @@ Thread::GetStatus (Stream &strm, uint32_ > } > > bool > -Thread::GetDescription (Stream &strm, lldb::DescriptionLevel level, bool > print_json) > +Thread::GetDescription (Stream &strm, lldb::DescriptionLevel level, bool > print_json_thread, bool print_json_stopinfo) > { > DumpUsingSettingsFormat (strm, 0); > strm.Printf("\n"); > > StructuredData::ObjectSP thread_info = GetExtendedInfo(); > - > - if (thread_info && print_json) > + StructuredData::ObjectSP stop_info = m_stop_info_sp->GetExtendedInfo(); > + > + if (print_json_thread || print_json_stopinfo) > { > - thread_info->Dump (strm); > - strm.Printf("\n"); > + if (thread_info && print_json_thread) > + { > + thread_info->Dump (strm); > + strm.Printf("\n"); > + } > + > + if (stop_info && print_json_stopinfo) > + { > + stop_info->Dump (strm); > + strm.Printf("\n"); > + } > + > return true; > } > > > Modified: lldb/trunk/source/lldb.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/source/lldb.cpp (original) > +++ lldb/trunk/source/lldb.cpp Fri Oct 10 18:43:03 2014 > @@ -93,6 +93,7 @@ > #include "Plugins/Process/gdb-remote/ProcessGDBRemote.h" > #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" > #include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h" > +#include > "Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h" > > using namespace lldb; > using namespace lldb_private; > @@ -156,6 +157,7 @@ lldb_private::Initialize () > JITLoaderGDB::Initialize(); > ProcessElfCore::Initialize(); > MemoryHistoryASan::Initialize(); > + AddressSanitizerRuntime::Initialize(); > > #if defined (__APPLE__) > > //---------------------------------------------------------------------- > @@ -247,6 +249,7 @@ lldb_private::Terminate () > JITLoaderGDB::Terminate(); > ProcessElfCore::Terminate(); > MemoryHistoryASan::Terminate(); > + AddressSanitizerRuntime::Terminate(); > > #if defined (__APPLE__) > DynamicLoaderMacOSXDYLD::Terminate(); > > Removed: lldb/trunk/test/functionalities/asan/TestAsan.py > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/asan/TestAsan.py?rev=219545&view=auto > ============================================================================== > --- lldb/trunk/test/functionalities/asan/TestAsan.py (original) > +++ lldb/trunk/test/functionalities/asan/TestAsan.py (removed) > @@ -1,117 +0,0 @@ > -""" > -Test that ASan memory history provider returns correct stack traces > -""" > - > -import os, time > -import unittest2 > -import lldb > -from lldbtest import * > -import lldbutil > - > -class AsanTestCase(TestBase): > - > - mydir = TestBase.compute_mydir(__file__) > - > - # The default compiler ("clang") may not support Address Sanitizer or it > - # may not have the debugging API which was recently added, so we're > calling > - # self.useBuiltClang() to use clang from the llvm-build directory instead > - > - @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires > Darwin") > - @skipIfRemote > - @dsym_test > - def test_with_dsym (self): > - compiler = self.findBuiltClang () > - self.buildDsym (None, compiler) > - self.asan_tests () > - > - @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default > - @skipIfRemote > - @dwarf_test > - def test_with_dwarf (self): > - compiler = self.findBuiltClang () > - self.buildDwarf (None, compiler) > - self.asan_tests () > - > - def setUp(self): > - # Call super's setUp(). > - TestBase.setUp(self) > - self.line_malloc = line_number('main.c', '// malloc line') > - self.line_malloc2 = line_number('main.c', '// malloc2 line') > - self.line_free = line_number('main.c', '// free line') > - self.line_breakpoint = line_number('main.c', '// break line') > - > - def asan_tests (self): > - exe = os.path.join (os.getcwd(), "a.out") > - self.expect("file " + exe, patterns = [ "Current executable set to > .*a.out" ]) > - > - self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint) > - > - # "memory history" command should not work without a process > - self.expect("memory history 0", > - error = True, > - substrs = ["invalid process"]) > - > - self.runCmd("run") > - > - # ASan will relaunch the process to insert its library. > - self.expect("thread list", "Process should be stopped due to exec.", > - substrs = ['stopped', 'stop reason = exec']) > - > - self.runCmd("continue") > - > - # the stop reason of the thread should be breakpoint. > - self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, > - substrs = ['stopped', 'stop reason = breakpoint']) > - > - # test that the ASan dylib is present > - self.expect("image lookup -n __asan_describe_address", > "__asan_describe_address should be present", > - substrs = ['1 match found']) > - > - # test the 'memory history' command > - self.expect("memory history 'pointer'", > - substrs = [ > - 'Memory allocated at', 'a.out`f1', 'main.c:%d' % > self.line_malloc, > - 'Memory deallocated at', 'a.out`f2', 'main.c:%d' % > self.line_free]) > - > - # do the same using SB API > - process = self.dbg.GetSelectedTarget().process > - val = > process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer") > - addr = val.GetValueAsUnsigned() > - threads = process.GetHistoryThreads(addr); > - self.assertEqual(threads.GetSize(), 2) > - > - history_thread = threads.GetThreadAtIndex(0) > - self.assertTrue(history_thread.num_frames >= 2) > - > self.assertEqual(history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(), > "main.c") > - self.assertEqual(history_thread.frames[1].GetLineEntry().GetLine(), > self.line_malloc) > - > - history_thread = threads.GetThreadAtIndex(1) > - self.assertTrue(history_thread.num_frames >= 2) > - > self.assertEqual(history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(), > "main.c") > - self.assertEqual(history_thread.frames[1].GetLineEntry().GetLine(), > self.line_free) > - > - # let's free the container (SBThreadCollection) and see if the > SBThreads still live > - threads = None > - self.assertTrue(history_thread.num_frames >= 2) > - > self.assertEqual(history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(), > "main.c") > - self.assertEqual(history_thread.frames[1].GetLineEntry().GetLine(), > self.line_free) > - > - # now let's break when an ASan report occurs and try the API then > - self.runCmd("breakpoint set -n __asan_report_error") > - > - self.runCmd("continue") > - > - # the stop reason of the thread should be breakpoint. > - self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, > - substrs = ['stopped', 'stop reason = breakpoint']) > - > - # make sure the 'memory history' command still works even when we're > generating a report now > - self.expect("memory history 'another_pointer'", > - substrs = [ > - 'Memory allocated at', 'a.out`f1', 'main.c:%d' % > self.line_malloc2]) > - > -if __name__ == '__main__': > - import atexit > - lldb.SBDebugger.Initialize() > - atexit.register(lambda: lldb.SBDebugger.Terminate()) > - unittest2.main() > > Added: lldb/trunk/test/functionalities/asan/TestReportData.py > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/asan/TestReportData.py?rev=219546&view=auto > ============================================================================== > --- lldb/trunk/test/functionalities/asan/TestReportData.py (added) > +++ lldb/trunk/test/functionalities/asan/TestReportData.py Fri Oct 10 > 18:43:03 2014 > @@ -0,0 +1,92 @@ > +""" > +Test the AddressSanitizer runtime support for report breakpoint and data > extraction. > +""" > + > +import os, time > +import unittest2 > +import lldb > +from lldbtest import * > +import lldbutil > +import json > + > +class AsanTestReportDataCase(TestBase): > + > + mydir = TestBase.compute_mydir(__file__) > + > + # The default compiler ("clang") may not support Address Sanitizer or it > + # may not have the debugging API which was recently added, so we're > calling > + # self.useBuiltClang() to use clang from the llvm-build directory instead > + > + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires > Darwin") > + @skipIfRemote > + @dsym_test > + def test_with_dsym (self): > + compiler = self.findBuiltClang () > + self.buildDsym (None, compiler) > + self.asan_tests () > + > + @skipIfRemote > + @dwarf_test > + def test_with_dwarf (self): > + compiler = self.findBuiltClang () > + self.buildDwarf (None, compiler) > + self.asan_tests () > + > + def setUp(self): > + # Call super's setUp(). > + TestBase.setUp(self) > + self.line_malloc = line_number('main.c', '// malloc line') > + self.line_malloc2 = line_number('main.c', '// malloc2 line') > + self.line_free = line_number('main.c', '// free line') > + self.line_breakpoint = line_number('main.c', '// break line') > + self.line_crash = line_number('main.c', '// BOOM line') > + > + def asan_tests (self): > + exe = os.path.join (os.getcwd(), "a.out") > + self.expect("file " + exe, patterns = [ "Current executable set to > .*a.out" ]) > + self.runCmd("run") > + > + # ASan will relaunch the process to insert its library. > + self.expect("thread list", "Process should be stopped due to exec.", > + substrs = ['stopped', 'stop reason = exec']) > + > + # no extended info when we have no ASan report > + thread = self.dbg.GetSelectedTarget().process.GetSelectedThread() > + s = lldb.SBStream() > + self.assertFalse(thread.GetStopReasonExtendedInfoAsJSON(s)) > + > + self.runCmd("continue") > + > + self.expect("thread list", "Process should be stopped due to ASan > report", > + substrs = ['stopped', 'stop reason = Use of deallocated memory > detected']) > + > + > self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), > lldb.eStopReasonInstrumentation) > + > + self.expect("bt", "The backtrace should show the crashing line", > + substrs = ['main.c:%d' % self.line_crash]) > + > + self.expect("thread info -s", "The extended stop info should contain > the ASan provided fields", > + substrs = ["access_size", "access_type", "address", "pc", > "description", "heap-use-after-free"]) > + > + output_lines = self.res.GetOutput().split('\n') > + json_line = output_lines[2] > + data = json.loads(json_line) > + self.assertEqual(data["description"], "heap-use-after-free") > + self.assertEqual(data["instrumentation_class"], "AddressSanitizer") > + self.assertEqual(data["stop_type"], "fatal_error") > + > + # now let's try the SB API > + process = self.dbg.GetSelectedTarget().process > + thread = process.GetSelectedThread() > + > + s = lldb.SBStream() > + self.assertTrue(thread.GetStopReasonExtendedInfoAsJSON(s)) > + s = s.GetData() > + data2 = json.loads(s) > + self.assertEqual(data, data2) > + > +if __name__ == '__main__': > + import atexit > + lldb.SBDebugger.Initialize() > + atexit.register(lambda: lldb.SBDebugger.Terminate()) > + unittest2.main() > > Modified: lldb/trunk/test/functionalities/asan/main.c > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/asan/main.c?rev=219546&r1=219545&r2=219546&view=diff > ============================================================================== > --- lldb/trunk/test/functionalities/asan/main.c (original) > +++ lldb/trunk/test/functionalities/asan/main.c Fri Oct 10 18:43:03 2014 > @@ -28,7 +28,7 @@ int main (int argc, char const *argv[]) > > printf("Hello world!\n"); // break line > > - pointer[0] = 'A'; // BOOM > + pointer[0] = 'A'; // BOOM line > > return 0; > } > > > _______________________________________________ > lldb-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits _______________________________________________ lldb-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
