to the DoHalt down in ProcessGDBRemote. I also moved the functionality that was in ProcessGDBRemote::DoHalt up into Process::Halt so not every class has to implement a tricky halt/resume on the internal state thread. The functionality is the same as it was before with two changes: - when we eat the event we now just reuse the event we consume when the private state thread is paused and set the interrupted bool on the event if needed - we also properly update the Process::m_public_state with the state of the event we consume. Prior to this, if you issued a "process halt" it would eat the event, not update the process state, and then produce a new event with the interrupted bit set and send it. Anyone listening to the event would get the stopped event with a process that whose state was set to "running". Fixed debugserver to not have to be spawned with the architecture of the inferior process. This worked fine for launching processes, but when attaching to processes by name or pid without a file in lldb, it would fail. Now debugserver can support multiple architectures for a native debug session on the current host. This currently means i386 and x86_64 are supported in the same binary and a x86_64 debugserver can attach to a i386 executable. This change involved a lot of changes to make sure we dynamically detect the correct registers for the inferior process. llvm-svn: 119680
137 lines
5.5 KiB
C++
137 lines
5.5 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 <tr1/memory> // for std::tr1::shared_ptr
|
|
|
|
#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"
|
|
|
|
class DNBBreakpoint;
|
|
class MachProcess;
|
|
|
|
class MachThread
|
|
{
|
|
public:
|
|
|
|
MachThread (MachProcess *process, thread_t thread = 0);
|
|
~MachThread ();
|
|
|
|
MachProcess * Process() { return m_process; }
|
|
const MachProcess *
|
|
Process() const { return m_process; }
|
|
nub_process_t ProcessID() const;
|
|
void Dump(uint32_t index);
|
|
thread_t ThreadID() const { return m_tid; }
|
|
thread_t InferiorThreadID() const;
|
|
|
|
uint32_t SequenceID() const { return m_seq_id; }
|
|
static bool ThreadIDIsValid(thread_t thread);
|
|
uint32_t Resume();
|
|
uint32_t Suspend();
|
|
uint32_t SuspendCount() const { return m_suspendCount; }
|
|
bool RestoreSuspendCount();
|
|
|
|
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
|
|
|
|
nub_break_t CurrentBreakpoint() const { return m_breakID; }
|
|
void SetCurrentBreakpoint(nub_break_t breakID) { m_breakID = breakID; }
|
|
uint32_t EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
|
|
uint32_t EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
|
|
bool DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
|
|
bool DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
|
|
|
|
nub_state_t GetState();
|
|
void SetState(nub_state_t state);
|
|
|
|
void ThreadWillResume (const DNBThreadResumeAction *thread_action);
|
|
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);
|
|
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();
|
|
}
|
|
|
|
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
|
|
thread_t m_tid; // The thread port for this thread
|
|
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
|
|
nub_break_t m_breakID; // Breakpoint that this thread is (stopped)/was(running) at (NULL for none)
|
|
struct thread_basic_info m_basicInfo; // Basic information for a thread used to see if a thread is valid
|
|
uint32_t m_suspendCount; // The current suspend count
|
|
MachException::Data m_stop_exception; // The best exception that describes why this thread is stopped
|
|
std::auto_ptr<DNBArchProtocol> m_arch_ap; // Arch specific information for register state and more
|
|
const DNBRegisterSetInfo *const m_reg_sets; // Register set information for this thread
|
|
nub_size_t n_num_reg_sets;
|
|
#ifdef THREAD_IDENTIFIER_INFO_COUNT
|
|
thread_identifier_info_data_t m_ident_info;
|
|
struct proc_threadinfo m_proc_threadinfo;
|
|
std::string m_dispatch_queue_name;
|
|
#endif
|
|
|
|
};
|
|
|
|
typedef std::tr1::shared_ptr<MachThread> MachThreadSP;
|
|
|
|
#endif
|