[Lldb-commits] [lldb] r259964 - Fix an issue where certain CommandObjects (or Options thereof) were being created once, bound to a specific CommandInterpreter (and hence a specific Debugger), and then cached for reuse across different Debugger instances
Enrico Granata via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 5 16:43:07 PST 2016
Author: enrico
Date: Fri Feb 5 18:43:07 2016
New Revision: 259964
URL: http://llvm.org/viewvc/llvm-project?rev=259964&view=rev
Log:
Fix an issue where certain CommandObjects (or Options thereof) were being created once, bound to a specific CommandInterpreter (and hence a specific Debugger), and then cached for reuse across different Debugger instances
Obviously, if the original Debugger goes away, those commands are holding on to now stale memory, which has the potential to cause crashes
Fixes rdar://24460882
Added:
lldb/trunk/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/
lldb/trunk/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py
Modified:
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
lldb/trunk/source/Target/LanguageRuntime.cpp
Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py?rev=259964&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/multidebugger_commands/TestMultipleDebuggersCommands.py Fri Feb 5 18:43:07 2016
@@ -0,0 +1,48 @@
+"""
+Test that commands do not try and hold on to stale CommandInterpreters in a multiple debuggers scenario
+"""
+
+from __future__ import print_function
+
+
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class MultipleDebuggersCommandsTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @no_debug_info_test
+ def test_multipledebuggers_commands(self):
+ """Test that commands do not try and hold on to stale CommandInterpreters in a multiple debuggers scenario"""
+ source_init_files = False
+ magic_text = "The following built-in commands may relate to 'env'"
+
+ debugger_1 = lldb.SBDebugger.Create(source_init_files)
+ interpreter_1 = debugger_1.GetCommandInterpreter()
+
+ retobj = lldb.SBCommandReturnObject()
+ interpreter_1.HandleCommand("apropos env", retobj)
+ self.assertTrue(magic_text in str(retobj), "[interpreter_1]: the output does not contain the correct words")
+
+ if self.TraceOn(): print(str(retobj))
+
+ lldb.SBDebugger.Destroy(debugger_1)
+
+ # now do this again with a different debugger - we shouldn't crash
+
+ debugger_2 = lldb.SBDebugger.Create(source_init_files)
+ interpreter_2 = debugger_2.GetCommandInterpreter()
+
+ retobj = lldb.SBCommandReturnObject()
+ interpreter_2.HandleCommand("apropos env", retobj)
+ self.assertTrue(magic_text in str(retobj), "[interpreter_2]: the output does not contain the correct words")
+
+ if self.TraceOn(): print(str(retobj))
+
+ lldb.SBDebugger.Destroy(debugger_2)
+
Modified: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp?rev=259964&r1=259963&r2=259964&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp Fri Feb 5 18:43:07 2016
@@ -4167,12 +4167,7 @@ RenderScriptRuntime::RenderScriptRuntime
lldb::CommandObjectSP
RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter &interpreter)
{
- static CommandObjectSP command_object;
- if (!command_object)
- {
- command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
- }
- return command_object;
+ return CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter));
}
RenderScriptRuntime::~RenderScriptRuntime() = default;
Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=259964&r1=259963&r2=259964&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Fri Feb 5 18:43:07 2016
@@ -41,6 +41,9 @@ using namespace lldb_private;
//------------------------------------------------------------------
PlatformPOSIX::PlatformPOSIX (bool is_host) :
Platform(is_host), // This is the local host platform
+m_option_group_platform_rsync(new OptionGroupPlatformRSync()),
+m_option_group_platform_ssh(new OptionGroupPlatformSSH()),
+m_option_group_platform_caching(new OptionGroupPlatformCaching()),
m_remote_platform_sp ()
{
}
@@ -69,14 +72,17 @@ PlatformPOSIX::GetModuleSpec (const File
lldb_private::OptionGroupOptions*
PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter)
{
- if (m_options.get() == NULL)
+ auto iter = m_options.find(&interpreter), end = m_options.end();
+ if (iter == end)
{
- m_options.reset(new OptionGroupOptions(interpreter));
- m_options->Append(new OptionGroupPlatformRSync());
- m_options->Append(new OptionGroupPlatformSSH());
- m_options->Append(new OptionGroupPlatformCaching());
+ std::unique_ptr<lldb_private::OptionGroupOptions> options(new OptionGroupOptions(interpreter));
+ options->Append(m_option_group_platform_rsync.get());
+ options->Append(m_option_group_platform_ssh.get());
+ options->Append(m_option_group_platform_caching.get());
+ m_options[&interpreter] = std::move(options);
}
- return m_options.get();
+
+ return m_options.at(&interpreter).get();
}
bool
@@ -675,29 +681,21 @@ PlatformPOSIX::ConnectRemote (Args& args
if (error.Success() && m_remote_platform_sp)
{
- if (m_options.get())
+ if (m_option_group_platform_rsync.get() && m_option_group_platform_ssh.get() && m_option_group_platform_caching.get())
{
- OptionGroupOptions* options = m_options.get();
- const OptionGroupPlatformRSync *m_rsync_options =
- static_cast<const OptionGroupPlatformRSync *>(options->GetGroupWithOption('r'));
- const OptionGroupPlatformSSH *m_ssh_options =
- static_cast<const OptionGroupPlatformSSH *>(options->GetGroupWithOption('s'));
- const OptionGroupPlatformCaching *m_cache_options =
- static_cast<const OptionGroupPlatformCaching *>(options->GetGroupWithOption('c'));
-
- if (m_rsync_options->m_rsync)
+ if (m_option_group_platform_rsync->m_rsync)
{
SetSupportsRSync(true);
- SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str());
- SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str());
- SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname);
+ SetRSyncOpts(m_option_group_platform_rsync->m_rsync_opts.c_str());
+ SetRSyncPrefix(m_option_group_platform_rsync->m_rsync_prefix.c_str());
+ SetIgnoresRemoteHostname(m_option_group_platform_rsync->m_ignores_remote_hostname);
}
- if (m_ssh_options->m_ssh)
+ if (m_option_group_platform_ssh->m_ssh)
{
SetSupportsSSH(true);
- SetSSHOpts(m_ssh_options->m_ssh_opts.c_str());
+ SetSSHOpts(m_option_group_platform_ssh->m_ssh_opts.c_str());
}
- SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str());
+ SetLocalCacheDirectory(m_option_group_platform_caching->m_cache_dir.c_str());
}
}
Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h?rev=259964&r1=259963&r2=259964&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h Fri Feb 5 18:43:07 2016
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <map>
#include <memory>
// Other libraries and framework includes
@@ -192,7 +193,11 @@ public:
ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
protected:
- std::unique_ptr<lldb_private::OptionGroupOptions> m_options;
+ std::unique_ptr<lldb_private::OptionGroupPlatformRSync> m_option_group_platform_rsync;
+ std::unique_ptr<lldb_private::OptionGroupPlatformSSH> m_option_group_platform_ssh;
+ std::unique_ptr<lldb_private::OptionGroupPlatformCaching> m_option_group_platform_caching;
+
+ std::map<lldb_private::CommandInterpreter*,std::unique_ptr<lldb_private::OptionGroupOptions>> m_options;
lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS
lldb_private::Error
Modified: lldb/trunk/source/Target/LanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/LanguageRuntime.cpp?rev=259964&r1=259963&r2=259964&view=diff
==============================================================================
--- lldb/trunk/source/Target/LanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/LanguageRuntime.cpp Fri Feb 5 18:43:07 2016
@@ -336,6 +336,10 @@ LanguageRuntime::InitializeCommands (Com
CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
if (command)
{
+ // the CommandObject vended by a Language plugin cannot be created once and cached because
+ // we may create multiple debuggers and need one instance of the command each - the implementing function
+ // is meant to create a new instance of the command each time it is invoked
+ assert(&command->GetCommandInterpreter() == &parent->GetCommandInterpreter() && "language plugin returned command for a mismatched CommandInterpreter");
parent->LoadSubCommand(command->GetCommandName(), command);
}
}
More information about the lldb-commits
mailing list