[Lldb-commits] [lldb] r217116 - ASan malloc/free history threads

Todd Fiala tfiala at google.com
Thu Sep 4 07:29:56 PDT 2014


Nice addition, Kuba!  I look forward to working with that :-)


On Wed, Sep 3, 2014 at 6:03 PM, Kuba Brecka <kuba.brecka at gmail.com> wrote:

> Author: kuba.brecka
> Date: Wed Sep  3 20:03:18 2014
> New Revision: 217116
>
> URL: http://llvm.org/viewvc/llvm-project?rev=217116&view=rev
> Log:
> ASan malloc/free history threads
>
> Reviewed at http://reviews.llvm.org/D4596
>
>
> Added:
>     lldb/trunk/include/lldb/Target/MemoryHistory.h
>     lldb/trunk/source/Plugins/MemoryHistory/
>     lldb/trunk/source/Plugins/MemoryHistory/CMakeLists.txt
>     lldb/trunk/source/Plugins/MemoryHistory/asan/
>     lldb/trunk/source/Plugins/MemoryHistory/asan/CMakeLists.txt
>     lldb/trunk/source/Plugins/MemoryHistory/asan/Makefile
>     lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
>     lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
>     lldb/trunk/source/Target/MemoryHistory.cpp
>     lldb/trunk/test/functionalities/asan/
>     lldb/trunk/test/functionalities/asan/Makefile
>     lldb/trunk/test/functionalities/asan/TestAsan.py
>     lldb/trunk/test/functionalities/asan/main.c
> Modified:
>     lldb/trunk/include/lldb/Core/PluginManager.h
>     lldb/trunk/include/lldb/lldb-forward.h
>     lldb/trunk/include/lldb/lldb-private-interfaces.h
>     lldb/trunk/lldb.xcodeproj/project.pbxproj
>     lldb/trunk/source/CMakeLists.txt
>     lldb/trunk/source/Commands/CommandObjectMemory.cpp
>     lldb/trunk/source/Core/PluginManager.cpp
>     lldb/trunk/source/Plugins/CMakeLists.txt
>     lldb/trunk/source/Plugins/Makefile
>     lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h
>     lldb/trunk/source/Target/CMakeLists.txt
>     lldb/trunk/source/lldb.cpp
>     lldb/trunk/test/lldbtest.py
>
> Modified: lldb/trunk/include/lldb/Core/PluginManager.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/PluginManager.h?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/include/lldb/Core/PluginManager.h (original)
> +++ lldb/trunk/include/lldb/Core/PluginManager.h Wed Sep  3 20:03:18 2014
> @@ -342,6 +342,23 @@ public:
>
>      static UnwindAssemblyCreateInstance
>      GetUnwindAssemblyCreateCallbackForPluginName (const ConstString
> &name);
> +
> +    //------------------------------------------------------------------
> +    // MemoryHistory
> +    //------------------------------------------------------------------
> +    static bool
> +    RegisterPlugin (const ConstString &name,
> +                    const char *description,
> +                    MemoryHistoryCreateInstance create_callback);
> +
> +    static bool
> +    UnregisterPlugin (MemoryHistoryCreateInstance create_callback);
> +
> +    static MemoryHistoryCreateInstance
> +    GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx);
> +
> +    static MemoryHistoryCreateInstance
> +    GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name);
>
>      //------------------------------------------------------------------
>      // Some plug-ins might register a DebuggerInitializeCallback
>
> Added: lldb/trunk/include/lldb/Target/MemoryHistory.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/MemoryHistory.h?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/include/lldb/Target/MemoryHistory.h (added)
> +++ lldb/trunk/include/lldb/Target/MemoryHistory.h Wed Sep  3 20:03:18 2014
> @@ -0,0 +1,42 @@
> +//===-- MemoryHistory.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_MemoryHistory_h_
> +#define liblldb_MemoryHistory_h_
> +
> +// C Includes
> +// C++ Includes
> +#include <vector>
> +
> +// 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::vector<lldb::ThreadSP> HistoryThreads;
> +
> +class MemoryHistory :
> +    public std::enable_shared_from_this<MemoryHistory>,
> +    public PluginInterface
> +{
> +public:
> +
> +    static lldb::MemoryHistorySP
> +    FindPlugin (const lldb::ProcessSP process);
> +
> +    virtual HistoryThreads
> +    GetHistoryThreads(lldb::addr_t address) = 0;
> +};
> +
> +} // namespace lldb_private
> +
> +#endif  // liblldb_MemoryHistory_h_
>
> Modified: lldb/trunk/include/lldb/lldb-forward.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/include/lldb/lldb-forward.h (original)
> +++ lldb/trunk/include/lldb/lldb-forward.h Wed Sep  3 20:03:18 2014
> @@ -116,6 +116,7 @@ class   Log;
>  class   LogChannel;
>  class   Mangled;
>  class   Materializer;
> +class   MemoryHistory;
>  class   Module;
>  class   ModuleList;
>  class   ModuleSpec;
> @@ -316,6 +317,7 @@ namespace lldb {
>      typedef std::shared_ptr<lldb_private::LineTable> LineTableSP;
>      typedef std::shared_ptr<lldb_private::Listener> ListenerSP;
>      typedef std::shared_ptr<lldb_private::LogChannel> LogChannelSP;
> +    typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP;
>      typedef std::shared_ptr<lldb_private::Module> ModuleSP;
>      typedef std::weak_ptr<lldb_private::Module> ModuleWP;
>      typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP;
>
> 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=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/include/lldb/lldb-private-interfaces.h (original)
> +++ lldb/trunk/include/lldb/lldb-private-interfaces.h Wed Sep  3 20:03:18
> 2014
> @@ -39,6 +39,7 @@ namespace lldb_private
>      typedef bool (*ThreadPlanShouldStopHereCallback) (ThreadPlan
> *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton);
>      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 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=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
> +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Sep  3 20:03:18 2014
> @@ -618,6 +618,8 @@
>                 4CF3D80C15AF4DC800845BF3 /* Security.framework in
> Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /*
> Security.framework */; };
>                 4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */
> = {isa = PBXBuildFile; fileRef = 4CF52AF41428291E0051E832 /*
> SBFileSpecList.h */; settings = {ATTRIBUTES = (Public, ); }; };
>                 4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources
> */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /*
> SBFileSpecList.cpp */; };
> +               8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources
> */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /*
> MemoryHistory.cpp */; };
> +               8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in
> Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /*
> MemoryHistoryASan.cpp */; };
>                 94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources
> */ = {isa = PBXBuildFile; fileRef = 94094C69163B6CD90083A547 /*
> ValueObjectCast.cpp */; };
>                 94145431175E63B500284436 /* lldb-versioning.h in Headers
> */ = {isa = PBXBuildFile; fileRef = 94145430175D7FDE00284436 /*
> lldb-versioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
>                 941BCC7F14E48C4000BB969C /* SBTypeFilter.h in Headers */ =
> {isa = PBXBuildFile; fileRef = 9461568614E355F2003A195C /* SBTypeFilter.h
> */; settings = {ATTRIBUTES = (Public, ); }; };
> @@ -1894,6 +1896,10 @@
>                 69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> path = Mutex.cpp; sourceTree = "<group>"; };
>                 69A01E1F1236C5D400C660B5 /* Symbols.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> path = Symbols.cpp; sourceTree = "<group>"; };
>                 69A01E201236C5D400C660B5 /* TimeValue.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> path = TimeValue.cpp; sourceTree = "<group>"; };
> +               8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp;
> sourceTree = "<group>"; };
> +               8C2D6A54197A1EBE006989C9 /* MemoryHistory.h */ = {isa =
> PBXFileReference; lastKnownFileType = sourcecode.c.h; name =
> MemoryHistory.h; path = include/lldb/Target/MemoryHistory.h; sourceTree =
> "<group>"; };
> +               8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */ =
> {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
> sourcecode.cpp.cpp; path = MemoryHistoryASan.cpp; sourceTree = "<group>"; };
> +               8C2D6A5B197A1FDC006989C9 /* MemoryHistoryASan.h */ = {isa
> = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h;
> path = MemoryHistoryASan.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>"; };
> @@ -2338,6 +2344,7 @@
>                 260C897110F57C5600BB2B04 /* Plugins */ = {
>                         isa = PBXGroup;
>                         children = (
> +                               8C2D6A58197A1FB9006989C9 /* MemoryHistory
> */,
>                                 26DB3E051379E7AD0080DC73 /* ABI */,
>                                 260C897210F57C5600BB2B04 /* Disassembler
> */,
>                                 260C897810F57C5600BB2B04 /* DynamicLoader
> */,
> @@ -3661,6 +3668,8 @@
>                                 4CB4430A12491DDA00C13DC2 /*
> LanguageRuntime.cpp */,
>                                 2690B36F1381D5B600ECFBAE /* Memory.h */,
>                                 2690B3701381D5C300ECFBAE /* Memory.cpp */,
> +                               8C2D6A54197A1EBE006989C9 /*
> MemoryHistory.h */,
> +                               8C2D6A52197A1EAF006989C9 /*
> MemoryHistory.cpp */,
>                                 2360092C193FB21500189DB1 /*
> MemoryRegionInfo.h */,
>                                 4CB443F612499B6E00C13DC2 /*
> ObjCLanguageRuntime.h */,
>                                 4CB443F212499B5000C13DC2 /*
> ObjCLanguageRuntime.cpp */,
> @@ -4114,6 +4123,23 @@
>                         path = source/Host/common;
>                         sourceTree = "<group>";
>                 };
> +               8C2D6A58197A1FB9006989C9 /* MemoryHistory */ = {
> +                       isa = PBXGroup;
> +                       children = (
> +                               8C2D6A59197A1FCD006989C9 /* asan */,
> +                       );
> +                       path = MemoryHistory;
> +                       sourceTree = "<group>";
> +               };
> +               8C2D6A59197A1FCD006989C9 /* asan */ = {
> +                       isa = PBXGroup;
> +                       children = (
> +                               8C2D6A5A197A1FDC006989C9 /*
> MemoryHistoryASan.cpp */,
> +                               8C2D6A5B197A1FDC006989C9 /*
> MemoryHistoryASan.h */,
> +                       );
> +                       path = asan;
> +                       sourceTree = "<group>";
> +               };
>                 9457596415349416005A9070 /* POSIX */ = {
>                         isa = PBXGroup;
>                         children = (
> @@ -4903,6 +4929,7 @@
>                                 2689005A13353E0400698AC0 /*
> ValueObjectList.cpp in Sources */,
>                                 2689005B13353E0400698AC0 /*
> ValueObjectRegister.cpp in Sources */,
>                                 2689005C13353E0400698AC0 /*
> ValueObjectVariable.cpp in Sources */,
> +                               8C2D6A53197A1EAF006989C9 /*
> MemoryHistory.cpp in Sources */,
>                                 2689005D13353E0400698AC0 /* VMRange.cpp in
> Sources */,
>                                 2689005E13353E0E00698AC0 /*
> ClangASTSource.cpp in Sources */,
>                                 2689005F13353E0E00698AC0 /*
> ClangFunction.cpp in Sources */,
> @@ -5126,6 +5153,7 @@
>                                 264A1300137252C700875C42 /*
> ARM64_DWARF_Registers.cpp in Sources */,
>                                 26DB3E161379E7AD0080DC73 /*
> ABIMacOSX_arm.cpp in Sources */,
>                                 26DB3E191379E7AD0080DC73 /*
> ABIMacOSX_arm64.cpp in Sources */,
> +                               8C2D6A5E197A250F006989C9 /*
> MemoryHistoryASan.cpp in Sources */,
>                                 26DB3E1C1379E7AD0080DC73 /*
> ABIMacOSX_i386.cpp in Sources */,
>                                 26DB3E1F1379E7AD0080DC73 /*
> ABISysV_x86_64.cpp in Sources */,
>                                 232CB61D191E00CD00EF39FC /*
> SoftwareBreakpoint.cpp in Sources */,
>
> Modified: lldb/trunk/source/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/CMakeLists.txt?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/CMakeLists.txt (original)
> +++ lldb/trunk/source/CMakeLists.txt Wed Sep  3 20:03:18 2014
> @@ -84,6 +84,7 @@ set( LLDB_USED_LIBS
>    lldbPluginInstructionARM64
>    lldbPluginObjectFilePECOFF
>    lldbPluginOSPython
> +  lldbPluginMemoryHistoryASan
>    )
>
>  # Need to export the API in the liblldb.dll for Windows
>
> Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
> +++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Wed Sep  3 20:03:18
> 2014
> @@ -33,8 +33,10 @@
>  #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
>  #include "lldb/Interpreter/OptionValueString.h"
>  #include "lldb/Symbol/TypeList.h"
> +#include "lldb/Target/MemoryHistory.h"
>  #include "lldb/Target/Process.h"
>  #include "lldb/Target/StackFrame.h"
> +#include "lldb/Target/Thread.h"
>
>  using namespace lldb;
>  using namespace lldb_private;
> @@ -1667,6 +1669,96 @@ protected:
>      OptionGroupWriteMemory m_memory_options;
>  };
>
> +//----------------------------------------------------------------------
> +// Get malloc/free history of a memory address.
> +//----------------------------------------------------------------------
> +class CommandObjectMemoryHistory : public CommandObjectParsed
> +{
> +public:
> +
> +    CommandObjectMemoryHistory (CommandInterpreter &interpreter) :
> +    CommandObjectParsed (interpreter,
> +                         "memory history",
> +                         "Prints out the recorded stack traces for
> allocation/deallocation of a memory address.",
> +                         NULL,
> +                         eFlagRequiresTarget | eFlagRequiresProcess |
> eFlagProcessMustBePaused | eFlagProcessMustBeLaunched)
> +    {
> +        CommandArgumentEntry arg1;
> +        CommandArgumentData addr_arg;
> +
> +        // Define the first (and only) variant of this arg.
> +        addr_arg.arg_type = eArgTypeAddress;
> +        addr_arg.arg_repetition = eArgRepeatPlain;
> +
> +        // There is only one variant this argument could be; put it into
> the argument entry.
> +        arg1.push_back (addr_arg);
> +
> +        // Push the data for the first argument into the m_arguments
> vector.
> +        m_arguments.push_back (arg1);
> +    }
> +
> +    virtual
> +    ~CommandObjectMemoryHistory ()
> +    {
> +    }
> +
> +    virtual const char *GetRepeatCommand (Args &current_command_args,
> uint32_t index)
> +    {
> +        return m_cmd_name.c_str();
> +    }
> +
> +protected:
> +    virtual bool
> +    DoExecute (Args& command, CommandReturnObject &result)
> +    {
> +        const size_t argc = command.GetArgumentCount();
> +
> +        if (argc == 0 || argc > 1)
> +        {
> +            result.AppendErrorWithFormat ("%s takes an address
> expression", m_cmd_name.c_str());
> +            result.SetStatus(eReturnStatusFailed);
> +            return false;
> +        }
> +
> +        Error error;
> +        lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
> +
>  command.GetArgumentAtIndex(0),
> +                                                   LLDB_INVALID_ADDRESS,
> +                                                   &error);
> +
> +        if (addr == LLDB_INVALID_ADDRESS)
> +        {
> +            result.AppendError("invalid address expression");
> +            result.AppendError(error.AsCString());
> +            result.SetStatus(eReturnStatusFailed);
> +            return false;
> +        }
> +
> +        Stream *output_stream = &result.GetOutputStream();
> +
> +        const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
> +        const MemoryHistorySP &memory_history =
> MemoryHistory::FindPlugin(process_sp);
> +
> +        if (! memory_history.get())
> +        {
> +            result.AppendError("no available memory history provider");
> +            result.SetStatus(eReturnStatusFailed);
> +            return false;
> +        }
> +
> +        HistoryThreads thread_list =
> memory_history->GetHistoryThreads(addr);
> +
> +        for (auto thread : thread_list) {
> +            thread->GetStatus(*output_stream, 0, UINT32_MAX, 0);
> +        }
> +
> +        result.SetStatus(eReturnStatusSuccessFinishResult);
> +
> +        return true;
> +    }
> +
> +};
> +
>
>
>  //-------------------------------------------------------------------------
>  // CommandObjectMemory
> @@ -1681,6 +1773,7 @@ CommandObjectMemory::CommandObjectMemory
>      LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind
> (interpreter)));
>      LoadSubCommand ("read",  CommandObjectSP (new CommandObjectMemoryRead
> (interpreter)));
>      LoadSubCommand ("write", CommandObjectSP (new
> CommandObjectMemoryWrite (interpreter)));
> +    LoadSubCommand ("history", CommandObjectSP (new
> CommandObjectMemoryHistory (interpreter)));
>  }
>
>  CommandObjectMemory::~CommandObjectMemory ()
>
> Modified: lldb/trunk/source/Core/PluginManager.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/PluginManager.cpp?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Core/PluginManager.cpp (original)
> +++ lldb/trunk/source/Core/PluginManager.cpp Wed Sep  3 20:03:18 2014
> @@ -2068,6 +2068,110 @@ PluginManager::GetUnwindAssemblyCreateCa
>      return NULL;
>  }
>
> +#pragma mark MemoryHistory
> +
> +struct MemoryHistoryInstance
> +{
> +    MemoryHistoryInstance() :
> +    name(),
> +    description(),
> +    create_callback(NULL)
> +    {
> +    }
> +
> +    ConstString name;
> +    std::string description;
> +    MemoryHistoryCreateInstance create_callback;
> +};
> +
> +typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
> +
> +static Mutex &
> +GetMemoryHistoryMutex ()
> +{
> +    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
> +    return g_instances_mutex;
> +}
> +
> +static MemoryHistoryInstances &
> +GetMemoryHistoryInstances ()
> +{
> +    static MemoryHistoryInstances g_instances;
> +    return g_instances;
> +}
> +
> +bool
> +PluginManager::RegisterPlugin
> +(
> + const ConstString &name,
> + const char *description,
> + MemoryHistoryCreateInstance create_callback
> + )
> +{
> +    if (create_callback)
> +    {
> +        MemoryHistoryInstance instance;
> +        assert ((bool)name);
> +        instance.name = name;
> +        if (description && description[0])
> +            instance.description = description;
> +        instance.create_callback = create_callback;
> +        Mutex::Locker locker (GetMemoryHistoryMutex ());
> +        GetMemoryHistoryInstances ().push_back (instance);
> +    }
> +    return false;
> +}
> +
> +bool
> +PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance
> create_callback)
> +{
> +    if (create_callback)
> +    {
> +        Mutex::Locker locker (GetMemoryHistoryMutex ());
> +        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
> +
> +        MemoryHistoryInstances::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;
> +}
> +
> +MemoryHistoryCreateInstance
> +PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
> +{
> +    Mutex::Locker locker (GetMemoryHistoryMutex ());
> +    MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
> +    if (idx < instances.size())
> +        return instances[idx].create_callback;
> +    return NULL;
> +}
> +
> +
> +MemoryHistoryCreateInstance
> +PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const
> ConstString &name)
> +{
> +    if (name)
> +    {
> +        Mutex::Locker locker (GetMemoryHistoryMutex ());
> +        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
> +
> +        MemoryHistoryInstances::iterator pos, end = instances.end();
> +        for (pos = instances.begin(); pos != end; ++ pos)
> +        {
> +            if (name == pos->name)
> +                return pos->create_callback;
> +        }
> +    }
> +    return NULL;
> +}
> +
>  void
>  PluginManager::DebuggerInitialize (Debugger &debugger)
>  {
>
> Modified: lldb/trunk/source/Plugins/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/CMakeLists.txt?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/CMakeLists.txt (original)
> +++ lldb/trunk/source/Plugins/CMakeLists.txt Wed Sep  3 20:03:18 2014
> @@ -4,6 +4,7 @@ add_subdirectory(DynamicLoader)
>  add_subdirectory(Instruction)
>  add_subdirectory(JITLoader)
>  add_subdirectory(LanguageRuntime)
> +add_subdirectory(MemoryHistory)
>  add_subdirectory(ObjectContainer)
>  add_subdirectory(ObjectFile)
>  add_subdirectory(OperatingSystem)
>
> Modified: lldb/trunk/source/Plugins/Makefile
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Makefile?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/Makefile (original)
> +++ lldb/trunk/source/Plugins/Makefile Wed Sep  3 20:03:18 2014
> @@ -24,7 +24,8 @@ DIRS := ABI/MacOSX-arm ABI/MacOSX-arm64
>         DynamicLoader/POSIX-DYLD \
>         DynamicLoader/Hexagon-DYLD \
>         OperatingSystem/Python \
> -       SymbolVendor/ELF
> +       SymbolVendor/ELF \
> +       MemoryHistory/asan
>
>  ifeq ($(HOST_OS),Darwin)
>  DIRS += Process/MacOSX-Kernel
>
> Added: lldb/trunk/source/Plugins/MemoryHistory/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/MemoryHistory/CMakeLists.txt?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/MemoryHistory/CMakeLists.txt (added)
> +++ lldb/trunk/source/Plugins/MemoryHistory/CMakeLists.txt Wed Sep  3
> 20:03:18 2014
> @@ -0,0 +1 @@
> +add_subdirectory(asan)
>
> Added: lldb/trunk/source/Plugins/MemoryHistory/asan/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/MemoryHistory/asan/CMakeLists.txt?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/MemoryHistory/asan/CMakeLists.txt (added)
> +++ lldb/trunk/source/Plugins/MemoryHistory/asan/CMakeLists.txt Wed Sep  3
> 20:03:18 2014
> @@ -0,0 +1,5 @@
> +set(LLVM_NO_RTTI 1)
> +
> +add_lldb_library(lldbPluginMemoryHistoryASan
> +  MemoryHistoryASan.cpp
> +  )
>
> Added: lldb/trunk/source/Plugins/MemoryHistory/asan/Makefile
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/MemoryHistory/asan/Makefile?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/MemoryHistory/asan/Makefile (added)
> +++ lldb/trunk/source/Plugins/MemoryHistory/asan/Makefile Wed Sep  3
> 20:03:18 2014
> @@ -0,0 +1,14 @@
> +##===- source/Plugins/MemoryHistory/asan/Makefile -------------*-
> 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 := lldbPluginMemoryHistoryASan
> +BUILD_ARCHIVE = 1
> +
> +include $(LLDB_LEVEL)/Makefile
>
> Added: lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
> (added)
> +++ lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp Wed
> Sep  3 20:03:18 2014
> @@ -0,0 +1,185 @@
> +//===-- MemoryHistoryASan.cpp -----------------------------------*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "MemoryHistoryASan.h"
> +
> +#include "lldb/Target/MemoryHistory.h"
> +
> +#include "lldb/lldb-private.h"
> +#include "lldb/Core/PluginInterface.h"
> +#include "lldb/Core/PluginManager.h"
> +#include "lldb/Target/ThreadList.h"
> +#include "lldb/Target/ExecutionContext.h"
> +#include "lldb/Target/Target.h"
> +#include "lldb/Target/Thread.h"
> +#include "lldb/Core/Module.h"
> +#include "Plugins/Process/Utility/HistoryThread.h"
> +#include "lldb/Core/ValueObject.h"
> +
> +using namespace lldb;
> +using namespace lldb_private;
> +
> +MemoryHistorySP
> +MemoryHistoryASan::CreateInstance (const ProcessSP &process_sp)
> +{
> +    if (!process_sp.get())
> +        return NULL;
> +
> +    Target & target = process_sp->GetTarget();
> +
> +    bool found_asan_runtime = false;
> +
> +    const ModuleList &target_modules = target.GetImages();
> +    Mutex::Locker modules_locker(target_modules.GetMutex());
> +    const size_t num_modules = target_modules.GetSize();
> +    for (size_t i = 0; i < num_modules; ++i)
> +    {
> +        Module *module_pointer =
> target_modules.GetModulePointerAtIndexUnlocked(i);
> +
> +        SymbolContextList sc_list;
> +        const bool include_symbols = true;
> +        const bool append = true;
> +        const bool include_inlines = true;
> +
> +        size_t num_matches =
> module_pointer->FindFunctions(ConstString("__asan_get_alloc_stack"), NULL,
> eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
> +
> +        if (num_matches)
> +        {
> +            found_asan_runtime = true;
> +            break;
> +        }
> +    }
> +
> +    if (! found_asan_runtime)
> +        return MemoryHistorySP();
> +
> +    return MemoryHistorySP(new MemoryHistoryASan(process_sp));
> +}
> +
> +void
> +MemoryHistoryASan::Initialize()
> +{
> +    PluginManager::RegisterPlugin (GetPluginNameStatic(),
> +                                   "ASan memory history provider.",
> +                                   CreateInstance);
> +}
> +
> +void
> +MemoryHistoryASan::Terminate()
> +{
> +    PluginManager::UnregisterPlugin (CreateInstance);
> +}
> +
> +
> +ConstString
> +MemoryHistoryASan::GetPluginNameStatic()
> +{
> +    static ConstString g_name("asan");
> +    return g_name;
> +}
> +
> +MemoryHistoryASan::MemoryHistoryASan(const ProcessSP &process_sp)
> +{
> +    this->m_process_sp = process_sp;
> +}
> +
> +const char *
> +memory_history_asan_command_format = R"(
> +    struct t {
> +        void *alloc_trace[256];
> +        size_t alloc_count;
> +        int alloc_tid;
> +
> +        void *free_trace[256];
> +        size_t free_count;
> +        int free_tid;
> +    } 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;
> +)";
> +
> +#define GET_STACK_FUNCTION_TIMEOUT_USEC 2*1000*1000
> +
> +HistoryThreads
> +MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address)
> +{
> +    ProcessSP process_sp = m_process_sp;
> +    ThreadSP thread_sp =
> m_process_sp->GetThreadList().GetSelectedThread();
> +    StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
> +
> +    if (!frame_sp)
> +    {
> +        return HistoryThreads();
> +    }
> +
> +    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 (m_process_sp->GetTarget().EvaluateExpression(expr.GetData(),
> frame_sp.get(), return_value_sp, options) != eExpressionCompleted)
> +    {
> +        return HistoryThreads();
> +    }
> +    if (!return_value_sp)
> +    {
> +        return HistoryThreads();
> +    }
> +
> +    HistoryThreads result;
> +
> +    int alloc_count =
> return_value_sp->GetValueForExpressionPath(".alloc_count")->GetValueAsUnsigned(0);
> +    int free_count =
> return_value_sp->GetValueForExpressionPath(".free_count")->GetValueAsUnsigned(0);
> +    tid_t alloc_tid =
> return_value_sp->GetValueForExpressionPath(".alloc_tid")->GetValueAsUnsigned(0);
> +    tid_t free_tid =
> return_value_sp->GetValueForExpressionPath(".free_tid")->GetValueAsUnsigned(0);
> +
> +    if (alloc_count > 0)
> +    {
> +        std::vector<lldb::addr_t> pcs;
> +        ValueObjectSP trace_sp =
> return_value_sp->GetValueForExpressionPath(".alloc_trace");
> +        for (int i = 0; i < alloc_count; i++) {
> +            addr_t pc = trace_sp->GetChildAtIndex(i,
> true)->GetValueAsUnsigned(0);
> +            pcs.push_back(pc);
> +        }
> +
> +        HistoryThread *history_thread = new HistoryThread(*process_sp,
> alloc_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("Memory allocated at");
> +        result.push_back(new_thread_sp);
> +    }
> +
> +    if (free_count > 0)
> +    {
> +        std::vector<lldb::addr_t> pcs;
> +        ValueObjectSP trace_sp =
> return_value_sp->GetValueForExpressionPath(".free_trace");
> +        for (int i = 0; i < free_count; i++) {
> +            addr_t pc = trace_sp->GetChildAtIndex(i,
> true)->GetValueAsUnsigned(0);
> +            pcs.push_back(pc);
> +        }
> +
> +        HistoryThread *history_thread = new HistoryThread(*process_sp,
> free_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("Memory deallocated at");
> +        result.push_back(new_thread_sp);
> +    }
> +
> +    return result;
> +}
>
> Added: lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
> (added)
> +++ lldb/trunk/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h Wed
> Sep  3 20:03:18 2014
> @@ -0,0 +1,62 @@
> +//===-- MemoryHistoryASan.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_MemoryHistoryASan_h_
> +#define liblldb_MemoryHistoryASan_h_
> +
> +// C Includes
> +// C++ Includes
> +// Other libraries and framework includes
> +// Project includes
> +#include "lldb/lldb-private.h"
> +#include "lldb/Target/ABI.h"
> +#include "lldb/Target/MemoryHistory.h"
> +#include "lldb/Target/Process.h"
> +
> +namespace lldb_private {
> +
> +class MemoryHistoryASan : public lldb_private::MemoryHistory
> +{
> +public:
> +
> +    static lldb::MemoryHistorySP
> +    CreateInstance (const lldb::ProcessSP &process_sp);
> +
> +    static void
> +    Initialize();
> +
> +    static void
> +    Terminate();
> +
> +    static lldb_private::ConstString
> +    GetPluginNameStatic();
> +
> +    virtual
> +    ~MemoryHistoryASan () {}
> +
> +    virtual lldb_private::ConstString
> +    GetPluginName() { return GetPluginNameStatic(); }
> +
> +    virtual uint32_t
> +    GetPluginVersion() { return 1; }
> +
> +    virtual lldb_private::HistoryThreads
> +    GetHistoryThreads(lldb::addr_t address);
> +
> +private:
> +
> +    MemoryHistoryASan(const lldb::ProcessSP &process_sp);
> +
> +    lldb::ProcessSP m_process_sp;
> +
> +};
> +
> +} // namespace lldb_private
> +
> +#endif  // liblldb_MemoryHistoryASan_h_
>
> Modified: lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h (original)
> +++ lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h Wed Sep  3
> 20:03:18 2014
> @@ -101,6 +101,18 @@ public:
>      {
>          m_thread_name = name;
>      }
> +
> +    virtual const char *
> +    GetName ()
> +    {
> +        return m_thread_name.c_str();
> +    }
> +
> +    virtual void
> +    SetName(const char *name)
> +    {
> +        m_thread_name = name;
> +    }
>
>  protected:
>      virtual lldb::StackFrameListSP
>
> Modified: lldb/trunk/source/Target/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/CMakeLists.txt?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Target/CMakeLists.txt (original)
> +++ lldb/trunk/source/Target/CMakeLists.txt Wed Sep  3 20:03:18 2014
> @@ -11,6 +11,7 @@ add_lldb_library(lldbTarget
>    JITLoaderList.cpp
>    LanguageRuntime.cpp
>    Memory.cpp
> +  MemoryHistory.cpp
>    NativeRegisterContext.cpp
>    NativeRegisterContextRegisterInfo.cpp
>    ObjCLanguageRuntime.cpp
>
> Added: lldb/trunk/source/Target/MemoryHistory.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/MemoryHistory.cpp?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/source/Target/MemoryHistory.cpp (added)
> +++ lldb/trunk/source/Target/MemoryHistory.cpp Wed Sep  3 20:03:18 2014
> @@ -0,0 +1,28 @@
> +//===-- MemoryHistory.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/MemoryHistory.h"
> +
> +#include "lldb/Core/PluginManager.h"
> +
> +using namespace lldb;
> +using namespace lldb_private;
> +
> +lldb::MemoryHistorySP
> +MemoryHistory::FindPlugin (const ProcessSP process)
> +{
> +    MemoryHistoryCreateInstance create_callback = NULL;
> +
> +    for (uint32_t idx = 0; (create_callback =
> PluginManager::GetMemoryHistoryCreateCallbackAtIndex(idx)) != NULL; ++idx)
> +    {
> +        return create_callback(process);
> +    }
> +
> +    return MemoryHistorySP();
> +}
>
> Modified: lldb/trunk/source/lldb.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/lldb.cpp (original)
> +++ lldb/trunk/source/lldb.cpp Wed Sep  3 20:03:18 2014
> @@ -92,6 +92,7 @@
>  #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
>  #include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
>  #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
> +#include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h"
>
>  using namespace lldb;
>  using namespace lldb_private;
> @@ -154,6 +155,7 @@ lldb_private::Initialize ()
>  #endif
>          JITLoaderGDB::Initialize();
>          ProcessElfCore::Initialize();
> +        MemoryHistoryASan::Initialize();
>
>  #if defined (__APPLE__)
>
>  //----------------------------------------------------------------------
> @@ -244,6 +246,7 @@ lldb_private::Terminate ()
>  #endif
>      JITLoaderGDB::Terminate();
>      ProcessElfCore::Terminate();
> +    MemoryHistoryASan::Terminate();
>
>  #if defined (__APPLE__)
>      DynamicLoaderMacOSXDYLD::Terminate();
>
> Added: lldb/trunk/test/functionalities/asan/Makefile
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/asan/Makefile?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/test/functionalities/asan/Makefile (added)
> +++ lldb/trunk/test/functionalities/asan/Makefile Wed Sep  3 20:03:18 2014
> @@ -0,0 +1,6 @@
> +LEVEL = ../../make
> +
> +C_SOURCES := main.c
> +CFLAGS := $(CFLAGS) -fsanitize=address -g
> +
> +include $(LEVEL)/Makefile.rules
>
> Added: lldb/trunk/test/functionalities/asan/TestAsan.py
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/asan/TestAsan.py?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/test/functionalities/asan/TestAsan.py (added)
> +++ lldb/trunk/test/functionalities/asan/TestAsan.py Wed Sep  3 20:03:18
> 2014
> @@ -0,0 +1,90 @@
> +"""
> +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")
> +    @dsym_test
> +    def test_with_dsym (self):
> +        compiler = self.findBuiltClang ()
> +        self.buildDsym (None, compiler)
> +        self.asan_tests ()
> +
> +    @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])
> +
> +        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/main.c
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/asan/main.c?rev=217116&view=auto
>
> ==============================================================================
> --- lldb/trunk/test/functionalities/asan/main.c (added)
> +++ lldb/trunk/test/functionalities/asan/main.c Wed Sep  3 20:03:18 2014
> @@ -0,0 +1,34 @@
> +//===-- main.c --------------------------------------------------*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +char *pointer;
> +char *another_pointer;
> +
> +void f1() {
> +    pointer = malloc(10); // malloc line
> +    another_pointer = malloc(20); // malloc2 line
> +}
> +
> +void f2() {
> +    free(pointer); // free line
> +}
> +
> +int main (int argc, char const *argv[])
> +{
> +    f1();
> +    f2();
> +
> +    printf("Hello world!\n"); // break line
> +
> +    pointer[0] = 'A'; // BOOM
> +
> +    return 0;
> +}
>
> Modified: lldb/trunk/test/lldbtest.py
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=217116&r1=217115&r2=217116&view=diff
>
> ==============================================================================
> --- lldb/trunk/test/lldbtest.py (original)
> +++ lldb/trunk/test/lldbtest.py Wed Sep  3 20:03:18 2014
> @@ -1325,6 +1325,22 @@ class Base(unittest2.TestCase):
>          if not module.buildDwarf(self, architecture, compiler,
> dictionary, clean):
>              raise Exception("Don't know how to build binary with dwarf")
>
> +    def findBuiltClang(self):
> +        """Tries to find and use Clang from the build directory as the
> compiler (instead of the system compiler)."""
> +        paths_to_try = [
> +          "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
> +          "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
> +          "llvm-build/Release/x86_64/Release/bin/clang",
> +          "llvm-build/Debug/x86_64/Debug/bin/clang",
> +        ]
> +        lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
> +        for p in paths_to_try:
> +            path = os.path.join(lldb_root_path, p)
> +            if os.path.exists(path):
> +                return path
> +
> +        return os.environ["CC"]
> +
>      def getBuildFlags(self, use_cpp11=True, use_libcxx=False,
> use_libstdcxx=False, use_pthreads=True):
>          """ Returns a dictionary (which can be provided to build*
> functions above) which
>              contains OS-specific build flags.
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>



-- 
Todd Fiala | Software Engineer | tfiala at google.com | 650-943-3180
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20140904/7b0d233c/attachment.html>


More information about the lldb-commits mailing list