Files
clang-p2996/lldb/tools/debugserver/source/MacOSX/MachThread.h
Jason Molenda 705b180964 Initial merge of some of the iOS 8 / Mac OS X Yosemite specific
lldb support.  I'll be doing more testing & cleanup but I wanted to
get the initial checkin done.

This adds a new SBExpressionOptions::SetLanguage API for selecting a
language of an expression.

I added adds a new SBThread::GetInfoItemByPathString for retriving
information about a thread from that thread's StructuredData.

I added a new StructuredData class for representing
key-value/array/dictionary information (e.g. JSON formatted data).
Helper functions to read JSON and create a StructuredData object,
and to print a StructuredData object in JSON format are included.

A few Cocoa / Cocoa Touch data formatters were updated by Enrico
to track changes in iOS 8 / Yosemite.

Before we query a thread's extended information, the system runtime may 
provide hints to the remote debug stub that it will use to retrieve values
out of runtime structures.  I added a new SystemRuntime method 
AddThreadExtendedInfoPacketHints which allows the SystemRuntime to add 
key-value type data to the initial request that we send to the remote stub.

The thread-format formatter string can now retrieve values out of a thread's
extended info structured data.  The default thread-format string picks up
two of these - thread.info.activity.name and thread.info.trace_messages.

I added a new "jThreadExtendedInfo" packet in debugserver; I will
add documentation to the lldb-gdb-remote.txt doc soon.  It accepts
JSON formatted arguments (most importantly, "thread":threadnum) and
it returns a variety of information regarding the thread to lldb
in JSON format.  This JSON return is scanned into a StructuredData
object that is associated with the thread; UI layers can query the
thread's StructuredData to see if key-values are present, and if
so, show them to the user.  These key-values are likely to be
specific to different targets with some commonality among many
targets.  For instance, many targets will be able to advertise the
pthread_t value for a thread.

I added an initial rough cut of "thread info" command which will print
the information about a thread from the jThreadExtendedInfo result.
I need to do more work to make this format reasonably.

Han Ming added calls into the pmenergy and pmsample libraries if
debugserver is run on Mac OS X Yosemite to get information about the
inferior's power use.

I added support to debugserver for gathering the Genealogy information
about threads, if it exists, and returning it in the jThreadExtendedInfo
JSON result.

llvm-svn: 210874
2014-06-13 02:37:02 +00:00

160 lines
6.9 KiB
C++

//===-- MachThread.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Created by Greg Clayton on 6/19/07.
//
//===----------------------------------------------------------------------===//
#ifndef __MachThread_h__
#define __MachThread_h__
#include <string>
#include <vector>
#include <libproc.h>
#include <mach/mach.h>
#include <pthread.h>
#include <sys/signal.h>
#include "PThreadCondition.h"
#include "PThreadMutex.h"
#include "MachException.h"
#include "DNBArch.h"
#include "DNBRegisterInfo.h"
#include "ThreadInfo.h"
class DNBBreakpoint;
class MachProcess;
class MachThreadList;
class MachThread
{
public:
MachThread (MachProcess *process, bool is_64_bit, uint64_t unique_thread_id = 0, thread_t mach_port_number = 0);
~MachThread ();
MachProcess * Process() { return m_process; }
const MachProcess *
Process() const { return m_process; }
nub_process_t ProcessID() const;
void Dump(uint32_t index);
uint64_t ThreadID() const { return m_unique_id; }
thread_t MachPortNumber() const { return m_mach_port_number; }
thread_t InferiorThreadID() const;
uint32_t SequenceID() const { return m_seq_id; }
static bool ThreadIDIsValid(uint64_t thread); // The 64-bit system-wide unique thread identifier
static bool MachPortNumberIsValid(thread_t thread); // The mach port # for this thread in debugserver namespace
void Resume(bool others_stopped);
void Suspend();
bool SetSuspendCountBeforeResume(bool others_stopped);
bool RestoreSuspendCountAfterStop();
bool GetRegisterState(int flavor, bool force);
bool SetRegisterState(int flavor);
uint64_t GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); // Get program counter
bool SetPC(uint64_t value); // Set program counter
uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer
DNBBreakpoint * CurrentBreakpoint();
uint32_t EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
uint32_t EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint, bool also_set_on_task);
bool DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
bool DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint, bool also_set_on_task);
uint32_t NumSupportedHardwareWatchpoints () const;
bool RollbackTransForHWP();
bool FinishTransForHWP();
nub_state_t GetState();
void SetState(nub_state_t state);
void ThreadWillResume (const DNBThreadResumeAction *thread_action, bool others_stopped = false);
bool ShouldStop(bool &step_more);
bool IsStepping();
bool ThreadDidStop();
bool NotifyException(MachException::Data& exc);
const MachException::Data& GetStopException() { return m_stop_exception; }
uint32_t GetNumRegistersInSet(int regSet) const;
const char * GetRegisterSetName(int regSet) const;
const DNBRegisterInfo *
GetRegisterInfo(int regSet, int regIndex) const;
void DumpRegisterState(int regSet);
const DNBRegisterSetInfo *
GetRegisterSetInfo(nub_size_t *num_reg_sets ) const;
bool GetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value );
bool SetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value );
nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len);
nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len);
uint32_t SaveRegisterState ();
bool RestoreRegisterState (uint32_t save_id);
void NotifyBreakpointChanged (const DNBBreakpoint *bp)
{
}
bool IsUserReady();
struct thread_basic_info *
GetBasicInfo ();
const char * GetBasicInfoAsString () const;
const char * GetName ();
DNBArchProtocol*
GetArchProtocol()
{
return m_arch_ap.get();
}
ThreadInfo::QoS GetRequestedQoS (nub_addr_t tsd, uint64_t dti_qos_class_index);
nub_addr_t GetPThreadT();
nub_addr_t GetDispatchQueueT();
nub_addr_t GetTSDAddressForThread (uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size);
static uint64_t GetGloballyUniqueThreadIDForMachPortID (thread_t mach_port_id);
protected:
static bool GetBasicInfo(thread_t threadID, struct thread_basic_info *basic_info);
bool
GetIdentifierInfo ();
// const char *
// GetDispatchQueueName();
//
MachProcess * m_process; // The process that owns this thread
uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t)
thread_t m_mach_port_number; // The mach port # for this thread in debugserver namesp.
uint32_t m_seq_id; // A Sequential ID that increments with each new thread
nub_state_t m_state; // The state of our process
PThreadMutex m_state_mutex; // Multithreaded protection for m_state
struct thread_basic_info m_basic_info; // Basic information for a thread used to see if a thread is valid
int32_t m_suspend_count; // The current suspend count > 0 means we have suspended m_suspendCount times,
// < 0 means we have resumed it m_suspendCount times.
MachException::Data m_stop_exception; // The best exception that describes why this thread is stopped
std::unique_ptr<DNBArchProtocol> m_arch_ap; // Arch specific information for register state and more
const DNBRegisterSetInfo * m_reg_sets; // Register set information for this thread
nub_size_t m_num_reg_sets;
thread_identifier_info_data_t m_ident_info;
struct proc_threadinfo m_proc_threadinfo;
std::string m_dispatch_queue_name;
bool m_is_64_bit;
// qos_class_t _pthread_qos_class_decode(pthread_priority_t priority, int *, unsigned long *);
unsigned int (*m_pthread_qos_class_decode) (unsigned long priority, int*, unsigned long *);
private:
friend class MachThreadList;
};
typedef std::shared_ptr<MachThread> MachThreadSP;
#endif