forked from OSchip/llvm-project
The OS plug-in can now get data from a python script that implements the protocol.
llvm-svn: 162540
This commit is contained in:
parent
98e00797cd
commit
435ce13937
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import lldb
|
||||
import struct
|
||||
|
||||
class PlugIn(object):
|
||||
"""Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
|
||||
|
@ -58,9 +59,9 @@ class PlugIn(object):
|
|||
|
||||
def get_register_data(self, tid):
|
||||
if tid == 0x111111111:
|
||||
return pack('Q',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21);
|
||||
return struct.pack('21Q',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21);
|
||||
elif tid == 0x222222222:
|
||||
return pack('Q',11,12,13,14,15,16,17,18,19,110,111,112,113,114,115,116,117,118,119,120,121);
|
||||
return struct.pack('21Q',11,12,13,14,15,16,17,18,19,110,111,112,113,114,115,116,117,118,119,120,121);
|
||||
elif tid == 0x333333333:
|
||||
return pack('Q',21,22,23,24,25,26,27,28,29,210,211,212,213,214,215,216,217,218,219,220,221);
|
||||
return struct.pack('21Q',21,22,23,24,25,26,27,28,29,210,211,212,213,214,215,216,217,218,219,220,221);
|
||||
|
||||
|
|
|
@ -90,8 +90,11 @@ namespace lldb_private {
|
|||
~PythonDataString ();
|
||||
|
||||
const char*
|
||||
GetString();
|
||||
|
||||
GetString() const;
|
||||
|
||||
size_t
|
||||
GetSize() const;
|
||||
|
||||
void
|
||||
SetString (const char* string);
|
||||
|
||||
|
|
|
@ -219,8 +219,8 @@ public:
|
|||
}
|
||||
|
||||
virtual lldb::ScriptInterpreterObjectSP
|
||||
OSPlugin_QueryForThreadInfo (lldb::ScriptInterpreterObjectSP object,
|
||||
lldb::tid_t thread_id)
|
||||
OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object,
|
||||
lldb::tid_t thread_id)
|
||||
{
|
||||
return lldb::ScriptInterpreterObjectSP();
|
||||
}
|
||||
|
|
|
@ -87,8 +87,8 @@ public:
|
|||
OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterObjectSP object);
|
||||
|
||||
virtual lldb::ScriptInterpreterObjectSP
|
||||
OSPlugin_QueryForThreadInfo (lldb::ScriptInterpreterObjectSP object,
|
||||
lldb::tid_t thread_id);
|
||||
OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object,
|
||||
lldb::tid_t thread_id);
|
||||
|
||||
virtual uint32_t
|
||||
CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor);
|
||||
|
|
|
@ -123,13 +123,21 @@ PythonDataString::~PythonDataString ()
|
|||
}
|
||||
|
||||
const char*
|
||||
PythonDataString::GetString()
|
||||
PythonDataString::GetString() const
|
||||
{
|
||||
if (m_object)
|
||||
return PyString_AsString(GetPythonObject());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
PythonDataString::GetSize() const
|
||||
{
|
||||
if (m_object)
|
||||
return PyString_Size(GetPythonObject());
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PythonDataString::SetString (const char* string)
|
||||
{
|
||||
|
|
|
@ -1845,8 +1845,8 @@ ScriptInterpreterPython::OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterOb
|
|||
}
|
||||
|
||||
lldb::ScriptInterpreterObjectSP
|
||||
ScriptInterpreterPython::OSPlugin_QueryForThreadInfo (lldb::ScriptInterpreterObjectSP object,
|
||||
lldb::tid_t thread_id)
|
||||
ScriptInterpreterPython::OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object,
|
||||
lldb::tid_t thread_id)
|
||||
{
|
||||
Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
|
||||
|
||||
|
|
|
@ -157,27 +157,50 @@ OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList
|
|||
if (!object_sp)
|
||||
return NULL;
|
||||
PythonDataObject pyobj((PyObject*)object_sp->GetObject());
|
||||
PythonDataArray array = pyobj.GetArrayObject();
|
||||
if(!array)
|
||||
return NULL;
|
||||
|
||||
// TODO: read from the dict
|
||||
|
||||
// and parse the returned dictionary. We need to pass in the a Dictionary
|
||||
// with the same kind of info we want back so we can reuse old threads, but
|
||||
// only create new ones.
|
||||
|
||||
// Make any constant strings once and cache the uniqued C string values
|
||||
// so we don't have to rehash them each time through this function call
|
||||
// dict thread_info_dict = python.get_thread_info()
|
||||
// for thread_info in thread_info_dict:
|
||||
// {
|
||||
// ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
// if (!thread_sp)
|
||||
// thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
|
||||
// new_thread_list.AddThread(thread_sp);
|
||||
// }
|
||||
new_thread_list = old_thread_list;
|
||||
PythonDataArray threads_array (pyobj.GetArrayObject());
|
||||
if (threads_array)
|
||||
{
|
||||
// const uint32_t num_old_threads = old_thread_list.GetSize(false);
|
||||
// for (uint32_t i=0; i<num_old_threads; ++i)
|
||||
// {
|
||||
// ThreadSP old_thread_sp(old_thread_list.GetThreadAtIndex(i, false));
|
||||
// if (old_thread_sp->GetID() < 0x10000)
|
||||
// new_thread_list.AddThread (old_thread_sp);
|
||||
// }
|
||||
|
||||
PythonDataString tid_pystr("tid");
|
||||
PythonDataString name_pystr("name");
|
||||
PythonDataString queue_pystr("queue");
|
||||
PythonDataString state_pystr("state");
|
||||
PythonDataString stop_reason_pystr("stop_reason");
|
||||
|
||||
const uint32_t num_threads = threads_array.GetSize();
|
||||
for (uint32_t i=0; i<num_threads; ++i)
|
||||
{
|
||||
PythonDataDictionary thread_dict(threads_array.GetItemAtIndex(i).GetDictionaryObject());
|
||||
if (thread_dict)
|
||||
{
|
||||
const tid_t tid = thread_dict.GetItemForKeyAsInteger(tid_pystr, LLDB_INVALID_THREAD_ID);
|
||||
const char *name = thread_dict.GetItemForKeyAsString (name_pystr);
|
||||
const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr);
|
||||
//const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
|
||||
//const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr);
|
||||
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp.reset (new ThreadMemory (m_process->shared_from_this(),
|
||||
tid,
|
||||
name,
|
||||
queue));
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_thread_list = old_thread_list;
|
||||
}
|
||||
return new_thread_list.GetSize(false) > 0;
|
||||
}
|
||||
|
||||
|
@ -189,24 +212,31 @@ OperatingSystemPython::ThreadWasSelected (Thread *thread)
|
|||
RegisterContextSP
|
||||
OperatingSystemPython::CreateRegisterContextForThread (Thread *thread)
|
||||
{
|
||||
|
||||
RegisterContextSP reg_ctx_sp;
|
||||
if (!m_interpreter || !m_python_object || !thread)
|
||||
return NULL;
|
||||
auto object_sp = m_interpreter->OSPlugin_QueryForThreadInfo(m_interpreter->MakeScriptObject(m_python_object),
|
||||
thread->GetID());
|
||||
if (!object_sp)
|
||||
return NULL;
|
||||
PythonDataObject pack_info_data_obj((PyObject*)object_sp->GetObject());
|
||||
if(!pack_info_data_obj)
|
||||
return NULL;
|
||||
auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object),
|
||||
thread->GetID());
|
||||
|
||||
RegisterContextSP reg_ctx_sp;
|
||||
// bytes b = get_register_context_data(thread)
|
||||
// if (b)
|
||||
// {
|
||||
// reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr));
|
||||
// // set bytes
|
||||
// }
|
||||
if (!object_sp)
|
||||
return NULL;
|
||||
|
||||
PythonDataString reg_context_data((PyObject*)object_sp->GetObject());
|
||||
if (reg_context_data)
|
||||
{
|
||||
DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(),
|
||||
reg_context_data.GetSize()));
|
||||
if (data_sp->GetByteSize())
|
||||
{
|
||||
printf("got %zu bytes of reg ctx data\n", data_sp->GetByteSize());
|
||||
RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS);
|
||||
if (reg_ctx_memory)
|
||||
{
|
||||
reg_ctx_sp.reset(reg_ctx_memory);
|
||||
reg_ctx_memory->SetAllRegisterData (data_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return reg_ctx_sp;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ RegisterContextMemory::~RegisterContextMemory()
|
|||
void
|
||||
RegisterContextMemory::InvalidateAllRegisters ()
|
||||
{
|
||||
SetAllRegisterValid (false);
|
||||
if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
|
||||
SetAllRegisterValid (false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -164,3 +165,10 @@ RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
RegisterContextMemory::SetAllRegisterData (const lldb::DataBufferSP &data_sp)
|
||||
{
|
||||
m_reg_data.SetData(data_sp);
|
||||
SetAllRegisterValid (true);
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ public:
|
|||
virtual bool
|
||||
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
|
||||
|
||||
void
|
||||
SetAllRegisterData (const lldb::DataBufferSP &data_sp);
|
||||
protected:
|
||||
|
||||
void
|
||||
|
|
|
@ -21,11 +21,29 @@ ThreadMemory::ThreadMemory (const ProcessSP &process_sp,
|
|||
tid_t tid,
|
||||
const ValueObjectSP &thread_info_valobj_sp) :
|
||||
Thread (process_sp, tid),
|
||||
m_thread_info_valobj_sp (thread_info_valobj_sp)
|
||||
m_thread_info_valobj_sp (thread_info_valobj_sp),
|
||||
m_name(),
|
||||
m_queue()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ThreadMemory::ThreadMemory (const lldb::ProcessSP &process_sp,
|
||||
lldb::tid_t tid,
|
||||
const char *name,
|
||||
const char *queue) :
|
||||
Thread (process_sp, tid),
|
||||
m_thread_info_valobj_sp (),
|
||||
m_name(),
|
||||
m_queue()
|
||||
{
|
||||
if (name)
|
||||
m_name = name;
|
||||
if (queue)
|
||||
m_queue = queue;
|
||||
}
|
||||
|
||||
|
||||
ThreadMemory::~ThreadMemory()
|
||||
{
|
||||
DestroyThread();
|
||||
|
|
|
@ -21,7 +21,12 @@ public:
|
|||
lldb::tid_t tid,
|
||||
const lldb::ValueObjectSP &thread_info_valobj_sp);
|
||||
|
||||
virtual
|
||||
ThreadMemory (const lldb::ProcessSP &process_sp,
|
||||
lldb::tid_t tid,
|
||||
const char *name,
|
||||
const char *queue);
|
||||
|
||||
virtual
|
||||
~ThreadMemory();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -39,6 +44,18 @@ public:
|
|||
virtual lldb::StopInfoSP
|
||||
GetPrivateStopReason ();
|
||||
|
||||
virtual const char *
|
||||
GetName ()
|
||||
{
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetQueueName ()
|
||||
{
|
||||
return m_queue.c_str();
|
||||
}
|
||||
|
||||
virtual bool
|
||||
WillResume (lldb::StateType resume_state);
|
||||
|
||||
|
@ -53,7 +70,8 @@ protected:
|
|||
// For ThreadMemory and subclasses
|
||||
//------------------------------------------------------------------
|
||||
lldb::ValueObjectSP m_thread_info_valobj_sp;
|
||||
|
||||
std::string m_name;
|
||||
std::string m_queue;
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
// For ThreadMemory only
|
||||
|
|
Loading…
Reference in New Issue