Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored in frozen objects ; now such reads transparently move from host to target as required - as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also removed code that enabled to recognize an expression result VO as such - introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO representing a T* or T[], and doing dereferences transparently in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData - as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it en lieu of doing the raw read itself - introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers, this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory) in public layer this returns an SBData, just like GetPointeeData() - introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values - added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing Solved a bug where global pointers to global variables were not dereferenced correctly for display New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128 Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file addresses that generate file address children UNLESS we have a live process) Updated help text for summary-string Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers Edited the syntax and help for some commands to have proper argument types llvm-svn: 139160
This commit is contained in:
@@ -18,9 +18,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBBreakpointLocation.h"
|
||||
#include "lldb/API/SBCommandReturnObject.h"
|
||||
#include "lldb/API/SBValue.h"
|
||||
#include "lldb/Breakpoint/StoppointCallbackContext.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/Timer.h"
|
||||
@@ -90,6 +88,36 @@ ReleasePythonLock ()
|
||||
PythonMutexPredicate().SetValue (LLDB_INVALID_THREAD_ID, eBroadcastAlways);
|
||||
}
|
||||
|
||||
ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *pi,
|
||||
FILE* tmp_fh,
|
||||
bool ns) :
|
||||
m_need_session(ns),
|
||||
m_release_lock(false),
|
||||
m_python_interpreter(pi),
|
||||
m_tmp_fh(tmp_fh)
|
||||
{
|
||||
// if Enter/LeaveSession() must be called, then m_python_interpreter must be != NULL
|
||||
assert(m_need_session && m_python_interpreter);
|
||||
if (!CurrentThreadHasPythonLock())
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
if (tmp_fh)
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
m_release_lock = true;
|
||||
}
|
||||
if (m_need_session)
|
||||
m_python_interpreter->EnterSession ();
|
||||
}
|
||||
|
||||
ScriptInterpreterPython::Locker::~Locker()
|
||||
{
|
||||
if (m_need_session)
|
||||
m_python_interpreter->LeaveSession ();
|
||||
if (m_release_lock)
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
|
||||
ScriptInterpreter (interpreter, eScriptLanguagePython),
|
||||
m_embedded_python_pty (),
|
||||
@@ -226,21 +254,10 @@ ScriptInterpreterPython::ResetOutputFileHandle (FILE *fh)
|
||||
m_dbg_stdout = fh;
|
||||
|
||||
FILE *tmp_fh = (m_dbg_stdout ? m_dbg_stdout : stdout);
|
||||
if (!CurrentThreadHasPythonLock ())
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh, "Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
EnterSession ();
|
||||
m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
|
||||
LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
else
|
||||
{
|
||||
EnterSession ();
|
||||
m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
|
||||
LeaveSession ();
|
||||
}
|
||||
|
||||
Locker py_lock(this, tmp_fh);
|
||||
|
||||
m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1400,25 +1417,12 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name
|
||||
void* ret_val;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
Locker py_lock(this, tmp_fh);
|
||||
ret_val = g_swig_synthetic_script (class_name,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
valobj);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_synthetic_script (class_name,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
valobj);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
@@ -1526,25 +1530,12 @@ ScriptInterpreterPython::CallPythonScriptFunction (const char *python_function_n
|
||||
&& *python_function_name)
|
||||
{
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
Locker py_lock(python_interpreter, tmp_fh);
|
||||
ret_val = g_swig_typescript_callback (python_function_name,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
valobj);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_typescript_callback (python_function_name,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
valobj);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1595,27 +1586,13 @@ ScriptInterpreterPython::BreakpointCallbackFunction
|
||||
{
|
||||
bool ret_val = true;
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
Locker py_lock(python_interpreter, tmp_fh);
|
||||
ret_val = g_swig_breakpoint_callback (python_function_name,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
stop_frame_sp,
|
||||
bp_loc_sp);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_breakpoint_callback (python_function_name,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
stop_frame_sp,
|
||||
bp_loc_sp);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
@@ -1758,55 +1735,47 @@ ScriptInterpreterPython::CalculateNumChildren (void *implementor)
|
||||
uint32_t ret_val = 0;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
Locker py_lock(python_interpreter, tmp_fh);
|
||||
ret_val = g_swig_calc_children (implementor);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_calc_children (implementor);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void*
|
||||
lldb::ValueObjectSP
|
||||
ScriptInterpreterPython::GetChildAtIndex (void *implementor, uint32_t idx)
|
||||
{
|
||||
if (!implementor)
|
||||
return 0;
|
||||
return lldb::ValueObjectSP();
|
||||
|
||||
if (!g_swig_get_child_index)
|
||||
return 0;
|
||||
if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
|
||||
return lldb::ValueObjectSP();
|
||||
|
||||
ScriptInterpreterPython *python_interpreter = this;
|
||||
|
||||
void* ret_val = NULL;
|
||||
void* child_ptr = NULL;
|
||||
lldb::SBValue* value_sb = NULL;
|
||||
lldb::ValueObjectSP ret_val;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_get_child_index (implementor,idx);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_get_child_index (implementor,idx);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
Locker py_lock(python_interpreter, tmp_fh);
|
||||
child_ptr = g_swig_get_child_index (implementor,idx);
|
||||
if (child_ptr != NULL && child_ptr != Py_None)
|
||||
{
|
||||
value_sb = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
|
||||
if (value_sb == NULL)
|
||||
Py_XDECREF(child_ptr);
|
||||
else
|
||||
ret_val = value_sb->get_sp();
|
||||
}
|
||||
else
|
||||
{
|
||||
Py_XDECREF(child_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
@@ -1826,21 +1795,10 @@ ScriptInterpreterPython::GetIndexOfChildWithName (void *implementor, const char*
|
||||
int ret_val = UINT32_MAX;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
Locker py_lock(python_interpreter, tmp_fh);
|
||||
ret_val = g_swig_get_index_child (implementor, child_name);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_get_index_child (implementor, child_name);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
@@ -1858,60 +1816,15 @@ ScriptInterpreterPython::UpdateSynthProviderInstance (void* implementor)
|
||||
ScriptInterpreterPython *python_interpreter = this;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
Locker py_lock(python_interpreter, tmp_fh);
|
||||
g_swig_update_provider (implementor);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
g_swig_update_provider (implementor);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
lldb::SBValue*
|
||||
ScriptInterpreterPython::CastPyObjectToSBValue (void* data)
|
||||
{
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
if (!g_swig_cast_to_sbvalue)
|
||||
return NULL;
|
||||
|
||||
ScriptInterpreterPython *python_interpreter = this;
|
||||
|
||||
lldb::SBValue* ret_val = NULL;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_cast_to_sbvalue (data);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_cast_to_sbvalue (data);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
|
||||
const char* args,
|
||||
@@ -1939,31 +1852,15 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
|
||||
std::string err_msg;
|
||||
|
||||
FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
|
||||
if (CurrentThreadHasPythonLock())
|
||||
|
||||
{
|
||||
python_interpreter->EnterSession ();
|
||||
Locker py_lock(python_interpreter, tmp_fh);
|
||||
ret_val = g_swig_call_command (impl_function,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
debugger_sp,
|
||||
args,
|
||||
err_msg,
|
||||
cmd_retobj);
|
||||
python_interpreter->LeaveSession ();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!GetPythonLock (1))
|
||||
fprintf (tmp_fh,
|
||||
"Python interpreter locked on another thread; waiting to acquire lock...\n");
|
||||
python_interpreter->EnterSession ();
|
||||
ret_val = g_swig_call_command (impl_function,
|
||||
python_interpreter->m_dictionary_name.c_str(),
|
||||
debugger_sp,
|
||||
args,
|
||||
err_msg,
|
||||
cmd_retobj);
|
||||
python_interpreter->LeaveSession ();
|
||||
ReleasePythonLock ();
|
||||
}
|
||||
|
||||
if (!ret_val)
|
||||
|
||||
Reference in New Issue
Block a user