Import lldb as of SVN r201577 (git 2bdc2f6)
(A number of files not required for the FreeBSD build have been removed.) Sponsored by: DARPA, AFRL
This commit is contained in:
parent
de889deb2c
commit
866dcdacfe
@ -33,13 +33,14 @@
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBFunction.h"
|
||||
#include "lldb/API/SBHostOS.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBInstruction.h"
|
||||
#include "lldb/API/SBInstructionList.h"
|
||||
#include "lldb/API/SBLineEntry.h"
|
||||
#include "lldb/API/SBListener.h"
|
||||
#include "lldb/API/SBModule.h"
|
||||
#include "lldb/API/SBProcess.h"
|
||||
#include "lldb/API/SBQueue.h"
|
||||
#include "lldb/API/SBQueueItem.h"
|
||||
#include "lldb/API/SBSourceManager.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
|
@ -118,6 +118,7 @@ class SBAddress
|
||||
friend class SBTarget;
|
||||
friend class SBThread;
|
||||
friend class SBValue;
|
||||
friend class SBQueueItem;
|
||||
|
||||
lldb_private::Address *
|
||||
operator->();
|
||||
|
@ -122,6 +122,36 @@ class SBCommandInterpreter
|
||||
|
||||
SBCommandInterpreter (lldb_private::CommandInterpreter *interpreter_ptr = NULL); // Access using SBDebugger::GetCommandInterpreter();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Return true if the command interpreter is the active IO handler.
|
||||
///
|
||||
/// This indicates that any input coming into the debugger handles will
|
||||
/// go to the command interpreter and will result in LLDB command line
|
||||
/// commands being executed.
|
||||
//----------------------------------------------------------------------
|
||||
bool
|
||||
IsActive ();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Get the string that needs to be written to the debugger stdin file
|
||||
/// handle when a control character is typed.
|
||||
///
|
||||
/// Some GUI programs will intercept "control + char" sequences and want
|
||||
/// to have them do what normally would happen when using a real
|
||||
/// terminal, so this function allows GUI programs to emulate this
|
||||
/// functionality.
|
||||
///
|
||||
/// @param[in] ch
|
||||
/// The character that was typed along with the control key
|
||||
///
|
||||
/// @return
|
||||
/// The string that should be written into the file handle that is
|
||||
/// feeding the input stream for the debugger, or NULL if there is
|
||||
/// no string for this control key.
|
||||
//----------------------------------------------------------------------
|
||||
const char *
|
||||
GetIOHandlerControlSequence(char ch);
|
||||
|
||||
protected:
|
||||
|
||||
lldb_private::CommandInterpreter &
|
||||
|
@ -17,6 +17,16 @@
|
||||
|
||||
namespace lldb {
|
||||
|
||||
|
||||
class SBInputReader
|
||||
{
|
||||
public:
|
||||
SBInputReader();
|
||||
~SBInputReader();
|
||||
SBError Initialize(lldb::SBDebugger&, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool);
|
||||
void SetIsDone(bool);
|
||||
bool IsActive() const;
|
||||
};
|
||||
class SBDebugger
|
||||
{
|
||||
public:
|
||||
@ -231,12 +241,6 @@ class SBDebugger
|
||||
void
|
||||
PushInputReader (lldb::SBInputReader &reader);
|
||||
|
||||
void
|
||||
NotifyTopInputReader (lldb::InputReaderAction notification);
|
||||
|
||||
bool
|
||||
InputReaderIsTopReader (const lldb::SBInputReader &reader);
|
||||
|
||||
const char *
|
||||
GetInstanceName ();
|
||||
|
||||
@ -313,6 +317,10 @@ class SBDebugger
|
||||
GetSyntheticForType (SBTypeNameSpecifier);
|
||||
#endif
|
||||
|
||||
void
|
||||
RunCommandInterpreter (bool auto_handle_events,
|
||||
bool spawn_thread);
|
||||
|
||||
private:
|
||||
|
||||
friend class SBCommandInterpreter;
|
||||
|
@ -48,7 +48,6 @@ class SBFileSpecList;
|
||||
class SBFrame;
|
||||
class SBFunction;
|
||||
class SBHostOS;
|
||||
class SBInputReader;
|
||||
class SBInstruction;
|
||||
class SBInstructionList;
|
||||
class SBLineEntry;
|
||||
|
@ -71,7 +71,6 @@ class SBError {
|
||||
friend class SBDebugger;
|
||||
friend class SBCommunication;
|
||||
friend class SBHostOS;
|
||||
friend class SBInputReader;
|
||||
friend class SBPlatform;
|
||||
friend class SBProcess;
|
||||
friend class SBThread;
|
||||
|
@ -1,97 +0,0 @@
|
||||
//===-- SBInputReader.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBInputReader_h_
|
||||
#define LLDB_SBInputReader_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBInputReader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t (*Callback) (void *baton,
|
||||
SBInputReader *reader,
|
||||
InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
SBInputReader ();
|
||||
|
||||
SBInputReader (const lldb::InputReaderSP &reader_sp);
|
||||
|
||||
SBInputReader (const lldb::SBInputReader &rhs);
|
||||
|
||||
~SBInputReader ();
|
||||
|
||||
|
||||
SBError
|
||||
Initialize (SBDebugger &debugger,
|
||||
Callback callback,
|
||||
void *callback_baton,
|
||||
lldb::InputReaderGranularity granularity,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo);
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
const lldb::SBInputReader &
|
||||
operator = (const lldb::SBInputReader &rhs);
|
||||
|
||||
bool
|
||||
IsActive () const;
|
||||
|
||||
bool
|
||||
IsDone () const;
|
||||
|
||||
void
|
||||
SetIsDone (bool value);
|
||||
|
||||
InputReaderGranularity
|
||||
GetGranularity ();
|
||||
|
||||
protected:
|
||||
friend class SBDebugger;
|
||||
|
||||
lldb_private::InputReader *
|
||||
operator->() const;
|
||||
|
||||
lldb::InputReaderSP &
|
||||
operator *();
|
||||
|
||||
const lldb::InputReaderSP &
|
||||
operator *() const;
|
||||
|
||||
lldb_private::InputReader *
|
||||
get() const;
|
||||
|
||||
lldb_private::InputReader &
|
||||
ref() const;
|
||||
|
||||
private:
|
||||
|
||||
static size_t
|
||||
PrivateCallback (void *baton,
|
||||
lldb_private::InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
lldb::InputReaderSP m_opaque_sp;
|
||||
Callback m_callback_function;
|
||||
void *m_callback_baton;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBInputReader_h_
|
@ -235,6 +235,25 @@ class SBModule
|
||||
lldb::SBTypeList
|
||||
FindTypes (const char* type);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get a type using its type ID.
|
||||
///
|
||||
/// Each symbol file reader will assign different user IDs to their
|
||||
/// types, but it is sometimes useful when debugging type issues to
|
||||
/// be able to grab a type using its type ID.
|
||||
///
|
||||
/// For DWARF debug info, the type ID is the DIE offset.
|
||||
///
|
||||
/// @param[in] uid
|
||||
/// The type user ID.
|
||||
///
|
||||
/// @return
|
||||
/// An SBType for the given type ID, or an empty SBType if the
|
||||
/// type was not found.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBType
|
||||
GetTypeByID (lldb::user_id_t uid);
|
||||
|
||||
lldb::SBType
|
||||
GetBasicType(lldb::BasicType type);
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBTarget.h"
|
||||
#include "lldb/API/SBQueue.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace lldb {
|
||||
@ -141,6 +142,15 @@ class SBProcess
|
||||
bool
|
||||
SetSelectedThreadByIndexID (uint32_t index_id);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Queue related functions
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
GetNumQueues ();
|
||||
|
||||
lldb::SBQueue
|
||||
GetQueueAtIndex (size_t index);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Stepping related functions
|
||||
//------------------------------------------------------------------
|
||||
@ -312,6 +322,7 @@ class SBProcess
|
||||
friend class SBTarget;
|
||||
friend class SBThread;
|
||||
friend class SBValue;
|
||||
friend class lldb_private::QueueImpl;
|
||||
|
||||
lldb::ProcessSP
|
||||
GetSP() const;
|
||||
|
83
include/lldb/API/SBQueue.h
Normal file
83
include/lldb/API/SBQueue.h
Normal file
@ -0,0 +1,83 @@
|
||||
//===-- SBQueue.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBQueue_h_
|
||||
#define LLDB_SBQueue_h_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/lldb-forward.h"
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBQueueItem.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBQueue
|
||||
{
|
||||
public:
|
||||
SBQueue ();
|
||||
|
||||
SBQueue (const QueueSP& queue_sp);
|
||||
|
||||
SBQueue (const SBQueue& rhs);
|
||||
|
||||
const SBQueue &
|
||||
operator= (const lldb::SBQueue& rhs);
|
||||
|
||||
~SBQueue();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
lldb::SBProcess
|
||||
GetProcess ();
|
||||
|
||||
lldb::queue_id_t
|
||||
GetQueueID () const;
|
||||
|
||||
const char *
|
||||
GetName () const;
|
||||
|
||||
uint32_t
|
||||
GetIndexID () const;
|
||||
|
||||
uint32_t
|
||||
GetNumThreads ();
|
||||
|
||||
lldb::SBThread
|
||||
GetThreadAtIndex (uint32_t);
|
||||
|
||||
uint32_t
|
||||
GetNumPendingItems ();
|
||||
|
||||
lldb::SBQueueItem
|
||||
GetPendingItemAtIndex (uint32_t);
|
||||
|
||||
protected:
|
||||
friend class SBProcess;
|
||||
|
||||
void
|
||||
SetQueue (const lldb::QueueSP& queue_sp);
|
||||
|
||||
void
|
||||
FetchThreads ();
|
||||
|
||||
void
|
||||
FetchItems ();
|
||||
|
||||
private:
|
||||
std::shared_ptr<lldb_private::QueueImpl> m_opaque_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBQueue_h_
|
58
include/lldb/API/SBQueueItem.h
Normal file
58
include/lldb/API/SBQueueItem.h
Normal file
@ -0,0 +1,58 @@
|
||||
//===-- SBQueueItem.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBQueueItem_h_
|
||||
#define LLDB_SBQueueItem_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBQueueItem
|
||||
{
|
||||
public:
|
||||
SBQueueItem ();
|
||||
|
||||
SBQueueItem (const lldb::QueueItemSP& queue_item_sp);
|
||||
|
||||
~SBQueueItem();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
lldb::QueueItemKind
|
||||
GetKind () const;
|
||||
|
||||
void
|
||||
SetKind (lldb::QueueItemKind kind);
|
||||
|
||||
lldb::SBAddress
|
||||
GetAddress () const;
|
||||
|
||||
void
|
||||
SetAddress (lldb::SBAddress addr);
|
||||
|
||||
void
|
||||
SetQueueItem (const lldb::QueueItemSP& queue_item_sp);
|
||||
|
||||
SBThread
|
||||
GetExtendedBacktraceThread (const char *type);
|
||||
|
||||
private:
|
||||
lldb::QueueItemSP m_queue_item_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBQueueItem_h_
|
@ -646,9 +646,47 @@ class SBTarget
|
||||
void
|
||||
Clear ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve a current load address into a section offset address.
|
||||
///
|
||||
/// @param[in] vm_addr
|
||||
/// A virtual address from the current process state that is to
|
||||
/// be translated into a section offset address.
|
||||
///
|
||||
/// @return
|
||||
/// An SBAddress which will be valid if \a vm_addr was
|
||||
/// successfully resolved into a section offset address, or an
|
||||
/// invalid SBAddress if \a vm_addr doesn't resolve to a section
|
||||
/// in a module.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBAddress
|
||||
ResolveLoadAddress (lldb::addr_t vm_addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve a current load address into a section offset address
|
||||
/// using the process stop ID to identify a time in the past.
|
||||
///
|
||||
/// @param[in] stop_id
|
||||
/// Each time a process stops, the process stop ID integer gets
|
||||
/// incremented. These stop IDs are used to identify past times
|
||||
/// and can be used in history objects as a cheap way to store
|
||||
/// the time at which the sample was taken. Specifying
|
||||
/// UINT32_MAX will always resolve the address using the
|
||||
/// currently loaded sections.
|
||||
///
|
||||
/// @param[in] vm_addr
|
||||
/// A virtual address from the current process state that is to
|
||||
/// be translated into a section offset address.
|
||||
///
|
||||
/// @return
|
||||
/// An SBAddress which will be valid if \a vm_addr was
|
||||
/// successfully resolved into a section offset address, or an
|
||||
/// invalid SBAddress if \a vm_addr doesn't resolve to a section
|
||||
/// in a module.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBAddress
|
||||
ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr);
|
||||
|
||||
SBSymbolContext
|
||||
ResolveSymbolContextForAddress (const SBAddress& addr,
|
||||
uint32_t resolve_scope);
|
||||
|
@ -214,6 +214,8 @@ class SBThread
|
||||
friend class SBProcess;
|
||||
friend class SBDebugger;
|
||||
friend class SBValue;
|
||||
friend class lldb_private::QueueImpl;
|
||||
friend class SBQueueItem;
|
||||
|
||||
void
|
||||
SetThread (const lldb::ThreadSP& lldb_object_sp);
|
||||
|
@ -105,6 +105,9 @@ class SBType
|
||||
lldb::SBType
|
||||
GetReferenceType();
|
||||
|
||||
lldb::SBType
|
||||
GetTypedefedType();
|
||||
|
||||
lldb::SBType
|
||||
GetDereferencedType();
|
||||
|
||||
|
@ -22,6 +22,9 @@ class SBTypeFormat
|
||||
|
||||
SBTypeFormat (lldb::Format format,
|
||||
uint32_t options = 0); // see lldb::eTypeOption values
|
||||
|
||||
SBTypeFormat (const char* type,
|
||||
uint32_t options = 0); // see lldb::eTypeOption values
|
||||
|
||||
SBTypeFormat (const lldb::SBTypeFormat &rhs);
|
||||
|
||||
@ -33,12 +36,18 @@ class SBTypeFormat
|
||||
lldb::Format
|
||||
GetFormat ();
|
||||
|
||||
const char*
|
||||
GetTypeName ();
|
||||
|
||||
uint32_t
|
||||
GetOptions();
|
||||
|
||||
void
|
||||
SetFormat (lldb::Format);
|
||||
|
||||
void
|
||||
SetTypeName (const char*);
|
||||
|
||||
void
|
||||
SetOptions (uint32_t);
|
||||
|
||||
@ -73,8 +82,15 @@ class SBTypeFormat
|
||||
|
||||
SBTypeFormat (const lldb::TypeFormatImplSP &);
|
||||
|
||||
enum class Type
|
||||
{
|
||||
eTypeKeepSame,
|
||||
eTypeFormat,
|
||||
eTypeEnum
|
||||
};
|
||||
|
||||
bool
|
||||
CopyOnWrite_Impl();
|
||||
CopyOnWrite_Impl(Type);
|
||||
|
||||
};
|
||||
|
||||
|
@ -612,12 +612,30 @@ class Breakpoint:
|
||||
/// Only the Target can make a breakpoint, and it owns the breakpoint lifespans.
|
||||
/// The constructor takes a filter and a resolver. Up in Target there are convenience
|
||||
/// variants that make breakpoints for some common cases.
|
||||
///
|
||||
/// @param[in] target
|
||||
/// The target in which the breakpoint will be set.
|
||||
///
|
||||
/// @param[in] filter_sp
|
||||
/// Shared pointer to the search filter that restricts the search domain of the breakpoint.
|
||||
///
|
||||
/// @param[in] resolver_sp
|
||||
/// Shared pointer to the resolver object that will determine breakpoint matches.
|
||||
///
|
||||
/// @param hardware
|
||||
/// If true, request a hardware breakpoint to be used to implement the breakpoint locations.
|
||||
///
|
||||
/// @param resolve_indirect_symbols
|
||||
/// If true, and the address of a given breakpoint location in this breakpoint is set on an
|
||||
/// indirect symbol (i.e. Symbol::IsIndirect returns true) then the actual breakpoint site will
|
||||
/// be set on the target of the indirect symbol.
|
||||
//------------------------------------------------------------------
|
||||
// This is the generic constructor
|
||||
Breakpoint(Target &target,
|
||||
lldb::SearchFilterSP &filter_sp,
|
||||
lldb::BreakpointResolverSP &resolver_sp,
|
||||
bool hardware);
|
||||
bool hardware,
|
||||
bool resolve_indirect_symbols = true);
|
||||
|
||||
friend class BreakpointLocation; // To call the following two when determining whether to stop.
|
||||
|
||||
@ -643,6 +661,7 @@ class Breakpoint:
|
||||
BreakpointOptions m_options; // Settable breakpoint options
|
||||
BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint.
|
||||
std::string m_kind_description;
|
||||
bool m_resolve_indirect_symbols;
|
||||
|
||||
void
|
||||
SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind);
|
||||
|
@ -321,7 +321,59 @@ class BreakpointLocation :
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
InvokeCallback (StoppointCallbackContext *context);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns whether we should resolve Indirect functions in setting the breakpoint site
|
||||
/// for this location.
|
||||
///
|
||||
/// @return
|
||||
/// \b true if the breakpoint SITE for this location should be set on the
|
||||
/// resolved location for Indirect functions.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
ShouldResolveIndirectFunctions ()
|
||||
{
|
||||
return m_should_resolve_indirect_functions;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns whether the address set in the breakpoint site for this location was found by resolving
|
||||
/// an indirect symbol.
|
||||
///
|
||||
/// @return
|
||||
/// \b true or \b false as given in the description above.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
IsIndirect ()
|
||||
{
|
||||
return m_is_indirect;
|
||||
}
|
||||
|
||||
void
|
||||
SetIsIndirect (bool is_indirect)
|
||||
{
|
||||
m_is_indirect = is_indirect;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns whether the address set in the breakpoint location was re-routed to the target of a
|
||||
/// re-exported symbol.
|
||||
///
|
||||
/// @return
|
||||
/// \b true or \b false as given in the description above.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
IsReExported ()
|
||||
{
|
||||
return m_is_reexported;
|
||||
}
|
||||
|
||||
void
|
||||
SetIsReExported (bool is_reexported)
|
||||
{
|
||||
m_is_reexported = is_reexported;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class BreakpointLocationList;
|
||||
friend class Process;
|
||||
@ -375,12 +427,16 @@ class BreakpointLocation :
|
||||
Breakpoint &owner,
|
||||
const Address &addr,
|
||||
lldb::tid_t tid,
|
||||
bool hardware);
|
||||
|
||||
bool hardware,
|
||||
bool check_for_resolver = true);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Data members:
|
||||
//------------------------------------------------------------------
|
||||
bool m_being_created;
|
||||
bool m_should_resolve_indirect_functions;
|
||||
bool m_is_reexported;
|
||||
bool m_is_indirect;
|
||||
Address m_address; ///< The address defining this location.
|
||||
Breakpoint &m_owner; ///< The breakpoint that produced this object.
|
||||
std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options.
|
||||
@ -389,6 +445,12 @@ class BreakpointLocation :
|
||||
Mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by multiple processes.
|
||||
size_t m_condition_hash; ///< For testing whether the condition source code changed.
|
||||
|
||||
void
|
||||
SetShouldResolveIndirectFunctions (bool do_resolve)
|
||||
{
|
||||
m_should_resolve_indirect_functions = do_resolve;
|
||||
}
|
||||
|
||||
void
|
||||
SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind);
|
||||
|
||||
|
@ -236,7 +236,7 @@ friend class Breakpoint;
|
||||
/// Returns breakpoint location id.
|
||||
//------------------------------------------------------------------
|
||||
lldb::BreakpointLocationSP
|
||||
Create (const Address &addr);
|
||||
Create (const Address &addr, bool resolve_indirect_symbols);
|
||||
|
||||
void
|
||||
StartRecordingNewLocations(BreakpointLocationCollection &new_locations);
|
||||
@ -246,6 +246,7 @@ friend class Breakpoint;
|
||||
|
||||
lldb::BreakpointLocationSP
|
||||
AddLocation (const Address &addr,
|
||||
bool resolve_indirect_symbols,
|
||||
bool *new_location = NULL);
|
||||
|
||||
bool
|
||||
|
@ -13,6 +13,7 @@
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
|
||||
@ -90,6 +91,7 @@ class ArchSpec
|
||||
eCore_x86_32_i486sx,
|
||||
|
||||
eCore_x86_64_x86_64,
|
||||
eCore_x86_64_x86_64h, // Haswell enabled x86_64
|
||||
eCore_uknownMach32,
|
||||
eCore_uknownMach64,
|
||||
kNumCores,
|
||||
@ -202,6 +204,27 @@ class ArchSpec
|
||||
llvm::Triple::ArchType
|
||||
GetMachine () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the distribution id of the architecture.
|
||||
///
|
||||
/// This will be something like "ubuntu", "fedora", etc. on Linux.
|
||||
///
|
||||
/// @return A ConstString ref containing the distribution id,
|
||||
/// potentially empty.
|
||||
//------------------------------------------------------------------
|
||||
const ConstString&
|
||||
GetDistributionId () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the distribution id of the architecture.
|
||||
///
|
||||
/// This will be something like "ubuntu", "fedora", etc. on Linux.
|
||||
/// This should be the same value returned by
|
||||
/// Host::GetDistributionId ().
|
||||
///------------------------------------------------------------------
|
||||
void
|
||||
SetDistributionId (const char* distribution_id);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tests if this ArchSpec is valid.
|
||||
///
|
||||
@ -400,6 +423,8 @@ class ArchSpec
|
||||
Core m_core;
|
||||
lldb::ByteOrder m_byte_order;
|
||||
|
||||
ConstString m_distribution_id;
|
||||
|
||||
// Called when m_def or m_entry are changed. Fills in all remaining
|
||||
// members with default values.
|
||||
void
|
||||
|
@ -286,6 +286,8 @@ class Communication : public Broadcaster
|
||||
virtual bool
|
||||
StopReadThread (Error *error_ptr = NULL);
|
||||
|
||||
virtual bool
|
||||
JoinReadThread (Error *error_ptr = NULL);
|
||||
//------------------------------------------------------------------
|
||||
/// Checks if there is a currently running read thread.
|
||||
///
|
||||
|
@ -11,9 +11,7 @@
|
||||
#define liblldb_ConnectionFileDescriptor_h_
|
||||
|
||||
// C Includes
|
||||
#ifdef _WIN32
|
||||
typedef unsigned short in_port_t;
|
||||
#else
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
@ -68,14 +66,17 @@ class ConnectionFileDescriptor :
|
||||
|
||||
// If the read file descriptor is a socket, then return
|
||||
// the port number that is being used by the socket.
|
||||
in_port_t
|
||||
uint16_t
|
||||
GetReadPort () const;
|
||||
|
||||
// If the write file descriptor is a socket, then return
|
||||
// the port number that is being used by the socket.
|
||||
in_port_t
|
||||
uint16_t
|
||||
GetWritePort () const;
|
||||
|
||||
uint16_t
|
||||
GetBoundPort (uint32_t timeout_sec);
|
||||
|
||||
protected:
|
||||
|
||||
typedef enum
|
||||
@ -95,7 +96,7 @@ class ConnectionFileDescriptor :
|
||||
BytesAvailable (uint32_t timeout_usec, Error *error_ptr);
|
||||
|
||||
lldb::ConnectionStatus
|
||||
SocketListen (uint16_t listen_port_num, Error *error_ptr);
|
||||
SocketListen (const char *host_and_port, Error *error_ptr);
|
||||
|
||||
lldb::ConnectionStatus
|
||||
ConnectTCP (const char *host_and_port, Error *error_ptr);
|
||||
@ -117,15 +118,16 @@ class ConnectionFileDescriptor :
|
||||
FDType m_fd_send_type;
|
||||
FDType m_fd_recv_type;
|
||||
std::unique_ptr<SocketAddress> m_udp_send_sockaddr;
|
||||
bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
|
||||
uint32_t m_socket_timeout_usec;
|
||||
int m_pipe_read; // A pipe that we select on the reading end of along with
|
||||
int m_pipe_write; // m_fd_recv so we can force ourselves out of the select.
|
||||
Mutex m_mutex;
|
||||
Mutex m_mutex;
|
||||
Predicate<uint16_t> m_port_predicate; // Used when binding to port zero to wait for the thread that creates the socket, binds and listens to resolve the port number
|
||||
bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
|
||||
bool m_shutting_down; // This marks that we are shutting down so if we get woken up from BytesAvailable
|
||||
// to disconnect, we won't try to read again.
|
||||
|
||||
static in_port_t
|
||||
static uint16_t
|
||||
GetSocketPort (int fd);
|
||||
|
||||
static int
|
||||
|
@ -19,9 +19,8 @@
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/Communication.h"
|
||||
#include "lldb/Core/InputReaderStack.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/Listener.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/SourceManager.h"
|
||||
#include "lldb/Core/UserID.h"
|
||||
#include "lldb/Core/UserSettingsController.h"
|
||||
@ -91,23 +90,25 @@ friend class SourceManager; // For GetSourceFileCache.
|
||||
void
|
||||
SetAsyncExecution (bool async);
|
||||
|
||||
File &
|
||||
lldb::StreamFileSP
|
||||
GetInputFile ()
|
||||
{
|
||||
return m_input_file.GetFile();
|
||||
return m_input_file_sp;
|
||||
}
|
||||
|
||||
File &
|
||||
lldb::StreamFileSP
|
||||
GetOutputFile ()
|
||||
{
|
||||
return m_output_file.GetFile();
|
||||
return m_output_file_sp;
|
||||
}
|
||||
|
||||
File &
|
||||
lldb::StreamFileSP
|
||||
GetErrorFile ()
|
||||
{
|
||||
return m_error_file.GetFile();
|
||||
return m_error_file_sp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
SetInputFileHandle (FILE *fh, bool tranfer_ownership);
|
||||
@ -124,18 +125,6 @@ friend class SourceManager; // For GetSourceFileCache.
|
||||
void
|
||||
RestoreInputTerminalState();
|
||||
|
||||
Stream&
|
||||
GetOutputStream ()
|
||||
{
|
||||
return m_output_file;
|
||||
}
|
||||
|
||||
Stream&
|
||||
GetErrorStream ()
|
||||
{
|
||||
return m_error_file;
|
||||
}
|
||||
|
||||
lldb::StreamSP
|
||||
GetAsyncOutputStream ();
|
||||
|
||||
@ -200,24 +189,38 @@ friend class SourceManager; // For GetSourceFileCache.
|
||||
void
|
||||
DispatchInputEndOfFile ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// If any of the streams are not set, set them to the in/out/err
|
||||
// stream of the top most input reader to ensure they at least have
|
||||
// something
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
DispatchInput (const char *bytes, size_t bytes_len);
|
||||
AdoptTopIOHandlerFilesIfInvalid (lldb::StreamFileSP &in,
|
||||
lldb::StreamFileSP &out,
|
||||
lldb::StreamFileSP &err);
|
||||
|
||||
void
|
||||
WriteToDefaultReader (const char *bytes, size_t bytes_len);
|
||||
|
||||
void
|
||||
PushInputReader (const lldb::InputReaderSP& reader_sp);
|
||||
PushIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
bool
|
||||
PopInputReader (const lldb::InputReaderSP& reader_sp);
|
||||
|
||||
void
|
||||
NotifyTopInputReader (lldb::InputReaderAction notification);
|
||||
|
||||
bool
|
||||
InputReaderIsTopReader (const lldb::InputReaderSP& reader_sp);
|
||||
PopIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
// Synchronously run an input reader until it is done
|
||||
void
|
||||
RunIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
bool
|
||||
IsTopIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
ConstString
|
||||
GetTopIOHandlerControlSequence(char ch);
|
||||
|
||||
bool
|
||||
HideTopIOHandler();
|
||||
|
||||
void
|
||||
RefreshTopIOHandler();
|
||||
|
||||
static lldb::DebuggerSP
|
||||
FindDebuggerWithID (lldb::user_id_t id);
|
||||
|
||||
@ -240,7 +243,7 @@ friend class SourceManager; // For GetSourceFileCache.
|
||||
|
||||
|
||||
void
|
||||
CleanUpInputReaders ();
|
||||
ClearIOHandlers ();
|
||||
|
||||
static int
|
||||
TestDebuggerRefCount ();
|
||||
@ -338,29 +341,65 @@ friend class SourceManager; // For GetSourceFileCache.
|
||||
bool
|
||||
LoadPlugin (const FileSpec& spec, Error& error);
|
||||
|
||||
void
|
||||
ExecuteIOHanders();
|
||||
|
||||
bool
|
||||
IsForwardingEvents ();
|
||||
|
||||
void
|
||||
EnableForwardEvents (const lldb::ListenerSP &listener_sp);
|
||||
|
||||
void
|
||||
CancelForwardEvents (const lldb::ListenerSP &listener_sp);
|
||||
protected:
|
||||
|
||||
static void
|
||||
DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len);
|
||||
|
||||
lldb::InputReaderSP
|
||||
GetCurrentInputReader ();
|
||||
|
||||
void
|
||||
ActivateInputReader (const lldb::InputReaderSP &reader_sp);
|
||||
friend class CommandInterpreter;
|
||||
|
||||
bool
|
||||
CheckIfTopInputReaderIsDone ();
|
||||
StartEventHandlerThread();
|
||||
|
||||
void
|
||||
StopEventHandlerThread();
|
||||
|
||||
static lldb::thread_result_t
|
||||
EventHandlerThread (lldb::thread_arg_t arg);
|
||||
|
||||
bool
|
||||
StartIOHandlerThread();
|
||||
|
||||
void
|
||||
StopIOHandlerThread();
|
||||
|
||||
static lldb::thread_result_t
|
||||
IOHandlerThread (lldb::thread_arg_t arg);
|
||||
|
||||
void
|
||||
DefaultEventHandler();
|
||||
|
||||
void
|
||||
HandleBreakpointEvent (const lldb::EventSP &event_sp);
|
||||
|
||||
void
|
||||
HandleProcessEvent (const lldb::EventSP &event_sp);
|
||||
|
||||
void
|
||||
HandleThreadEvent (const lldb::EventSP &event_sp);
|
||||
|
||||
size_t
|
||||
GetProcessSTDOUT (Process *process, Stream *stream);
|
||||
|
||||
size_t
|
||||
GetProcessSTDERR (Process *process, Stream *stream);
|
||||
|
||||
SourceManager::SourceFileCache &
|
||||
GetSourceFileCache ()
|
||||
{
|
||||
return m_source_file_cache;
|
||||
}
|
||||
Communication m_input_comm;
|
||||
StreamFile m_input_file;
|
||||
StreamFile m_output_file;
|
||||
StreamFile m_error_file;
|
||||
lldb::StreamFileSP m_input_file_sp;
|
||||
lldb::StreamFileSP m_output_file_sp;
|
||||
lldb::StreamFileSP m_error_file_sp;
|
||||
TerminalState m_terminal_state;
|
||||
TargetList m_target_list;
|
||||
PlatformList m_platform_list;
|
||||
@ -370,8 +409,7 @@ friend class SourceManager; // For GetSourceFileCache.
|
||||
// source file cache.
|
||||
std::unique_ptr<CommandInterpreter> m_command_interpreter_ap;
|
||||
|
||||
InputReaderStack m_input_reader_stack;
|
||||
std::string m_input_reader_data;
|
||||
IOHandlerStack m_input_reader_stack;
|
||||
typedef std::map<std::string, lldb::StreamWP> LogStreamMap;
|
||||
LogStreamMap m_log_streams;
|
||||
lldb::StreamSP m_log_callback_stream_sp;
|
||||
@ -379,7 +417,10 @@ friend class SourceManager; // For GetSourceFileCache.
|
||||
static LoadPluginCallbackType g_load_plugin_callback;
|
||||
typedef std::vector<lldb::DynamicLibrarySP> LoadedPluginsList;
|
||||
LoadedPluginsList m_loaded_plugins;
|
||||
|
||||
lldb::thread_t m_event_handler_thread;
|
||||
lldb::thread_t m_io_handler_thread;
|
||||
lldb::ListenerSP m_forward_listener_sp;
|
||||
bool m_event_handler_thread_alive;
|
||||
void
|
||||
InstanceInitialize ();
|
||||
|
||||
|
@ -175,6 +175,9 @@ class InstructionList
|
||||
uint32_t
|
||||
GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
|
||||
|
||||
uint32_t
|
||||
GetIndexOfInstructionAtAddress (const Address &addr);
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
|
646
include/lldb/Core/IOHandler.h
Normal file
646
include/lldb/Core/IOHandler.h
Normal file
@ -0,0 +1,646 @@
|
||||
//===-- IOHandler.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_IOHandler_h_
|
||||
#define liblldb_IOHandler_h_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/Flags.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Core/ValueObjectList.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace curses
|
||||
{
|
||||
class Application;
|
||||
typedef std::unique_ptr<Application> ApplicationAP;
|
||||
}
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandler (Debugger &debugger);
|
||||
|
||||
IOHandler (Debugger &debugger,
|
||||
const lldb::StreamFileSP &input_sp,
|
||||
const lldb::StreamFileSP &output_sp,
|
||||
const lldb::StreamFileSP &error_sp,
|
||||
uint32_t flags);
|
||||
|
||||
virtual
|
||||
~IOHandler ();
|
||||
|
||||
// Each IOHandler gets to run until it is done. It should read data
|
||||
// from the "in" and place output into "out" and "err and return
|
||||
// when done.
|
||||
virtual void
|
||||
Run () = 0;
|
||||
|
||||
// Hide any characters that have been displayed so far so async
|
||||
// output can be displayed. Refresh() will be called after the
|
||||
// output has been displayed.
|
||||
virtual void
|
||||
Hide () = 0;
|
||||
|
||||
// Called when the async output has been received in order to update
|
||||
// the input reader (refresh the prompt and redisplay any current
|
||||
// line(s) that are being edited
|
||||
virtual void
|
||||
Refresh () = 0;
|
||||
|
||||
virtual void
|
||||
Interrupt () = 0;
|
||||
|
||||
virtual void
|
||||
GotEOF() = 0;
|
||||
|
||||
virtual bool
|
||||
IsActive ()
|
||||
{
|
||||
return m_active && !m_done;
|
||||
}
|
||||
|
||||
virtual void
|
||||
SetIsDone (bool b)
|
||||
{
|
||||
m_done = b;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GetIsDone ()
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
virtual void
|
||||
Activate ()
|
||||
{
|
||||
m_active = true;
|
||||
}
|
||||
|
||||
virtual void
|
||||
Deactivate ()
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetPrompt ()
|
||||
{
|
||||
// Prompt support isn't mandatory
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
SetPrompt (const char *prompt)
|
||||
{
|
||||
// Prompt support isn't mandatory
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
int
|
||||
GetInputFD();
|
||||
|
||||
int
|
||||
GetOutputFD();
|
||||
|
||||
int
|
||||
GetErrorFD();
|
||||
|
||||
FILE *
|
||||
GetInputFILE();
|
||||
|
||||
FILE *
|
||||
GetOutputFILE();
|
||||
|
||||
FILE *
|
||||
GetErrorFILE();
|
||||
|
||||
lldb::StreamFileSP &
|
||||
GetInputStreamFile();
|
||||
|
||||
lldb::StreamFileSP &
|
||||
GetOutputStreamFile();
|
||||
|
||||
lldb::StreamFileSP &
|
||||
GetErrorStreamFile();
|
||||
|
||||
Debugger &
|
||||
GetDebugger()
|
||||
{
|
||||
return m_debugger;
|
||||
}
|
||||
|
||||
void *
|
||||
GetUserData ()
|
||||
{
|
||||
return m_user_data;
|
||||
}
|
||||
|
||||
void
|
||||
SetUserData (void *user_data)
|
||||
{
|
||||
m_user_data = user_data;
|
||||
}
|
||||
|
||||
Flags &
|
||||
GetFlags ()
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
const Flags &
|
||||
GetFlags () const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check if the input is being supplied interactively by a user
|
||||
///
|
||||
/// This will return true if the input stream is a terminal (tty or
|
||||
/// pty) and can cause IO handlers to do different things (like
|
||||
/// for a comfirmation when deleting all breakpoints).
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
GetIsInteractive ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check if the input is coming from a real terminal.
|
||||
///
|
||||
/// A real terminal has a valid size with a certain number of rows
|
||||
/// and colums. If this function returns true, then terminal escape
|
||||
/// sequences are expected to work (cursor movement escape sequences,
|
||||
/// clearning lines, etc).
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
GetIsRealTerminal ();
|
||||
|
||||
protected:
|
||||
Debugger &m_debugger;
|
||||
lldb::StreamFileSP m_input_sp;
|
||||
lldb::StreamFileSP m_output_sp;
|
||||
lldb::StreamFileSP m_error_sp;
|
||||
Flags m_flags;
|
||||
void *m_user_data;
|
||||
bool m_done;
|
||||
bool m_active;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (IOHandler);
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// A delegate class for use with IOHandler subclasses.
|
||||
///
|
||||
/// The IOHandler delegate is designed to be mixed into classes so
|
||||
/// they can use an IOHandler subclass to fetch input and notify the
|
||||
/// object that inherits from this delegate class when a token is
|
||||
/// received.
|
||||
//------------------------------------------------------------------
|
||||
class IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
enum class Completion {
|
||||
None,
|
||||
LLDBCommand,
|
||||
Expression
|
||||
};
|
||||
|
||||
IOHandlerDelegate (Completion completion = Completion::None) :
|
||||
m_completion(completion),
|
||||
m_io_handler_done (false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~IOHandlerDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int
|
||||
IOHandlerComplete (IOHandler &io_handler,
|
||||
const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Called when a line or lines have been retrieved.
|
||||
///
|
||||
/// This funtion can handle the current line and possibly call
|
||||
/// IOHandler::SetIsDone(true) when the IO handler is done like when
|
||||
/// "quit" is entered as a command, of when an empty line is
|
||||
/// received. It is up to the delegate to determine when a line
|
||||
/// should cause a IOHandler to exit.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Called when a line in \a lines has been updated when doing
|
||||
/// multi-line input.
|
||||
///
|
||||
/// @return
|
||||
/// Return an enumeration to indicate the status of the current
|
||||
/// line:
|
||||
/// Success - The line is good and should be added to the
|
||||
/// multiple lines
|
||||
/// Error - There is an error with the current line and it
|
||||
/// need to be re-edited before it is acceptable
|
||||
/// Done - The lines collection is complete and ready to be
|
||||
/// returned.
|
||||
//------------------------------------------------------------------
|
||||
virtual LineStatus
|
||||
IOHandlerLinesUpdated (IOHandler &io_handler,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error)
|
||||
{
|
||||
return LineStatus::Done; // Stop getting lines on the first line that is updated
|
||||
// subclasses should do something more intelligent here.
|
||||
// This function will not be called on IOHandler objects
|
||||
// that are getting single lines.
|
||||
}
|
||||
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
protected:
|
||||
Completion m_completion; // Support for common builtin completions
|
||||
bool m_io_handler_done;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// IOHandlerDelegateMultiline
|
||||
//
|
||||
// A IOHandlerDelegate that handles terminating multi-line input when
|
||||
// the last line is equal to "end_line" which is specified in the
|
||||
// constructor.
|
||||
//----------------------------------------------------------------------
|
||||
class IOHandlerDelegateMultiline :
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
IOHandlerDelegateMultiline (const char *end_line,
|
||||
Completion completion = Completion::None) :
|
||||
IOHandlerDelegate (completion),
|
||||
m_end_line((end_line && end_line[0]) ? end_line : "")
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~IOHandlerDelegateMultiline ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
if (ch == 'd')
|
||||
return ConstString (m_end_line + "\n");
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
virtual LineStatus
|
||||
IOHandlerLinesUpdated (IOHandler &io_handler,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error)
|
||||
{
|
||||
if (line_idx == UINT32_MAX)
|
||||
{
|
||||
// Remove the last empty line from "lines" so it doesn't appear
|
||||
// in our final expression and return true to indicate we are done
|
||||
// getting lines
|
||||
lines.PopBack();
|
||||
return LineStatus::Done;
|
||||
}
|
||||
else if (line_idx + 1 == lines.GetSize())
|
||||
{
|
||||
// The last line was edited, if this line is empty, then we are done
|
||||
// getting our multiple lines.
|
||||
if (lines[line_idx] == m_end_line)
|
||||
return LineStatus::Done;
|
||||
}
|
||||
return LineStatus::Success;
|
||||
}
|
||||
protected:
|
||||
const std::string m_end_line;
|
||||
};
|
||||
|
||||
|
||||
class IOHandlerEditline : public IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandlerEditline (Debugger &debugger,
|
||||
const char *editline_name, // Used for saving history files
|
||||
const char *prompt,
|
||||
bool multi_line,
|
||||
IOHandlerDelegate &delegate);
|
||||
|
||||
IOHandlerEditline (Debugger &debugger,
|
||||
const lldb::StreamFileSP &input_sp,
|
||||
const lldb::StreamFileSP &output_sp,
|
||||
const lldb::StreamFileSP &error_sp,
|
||||
uint32_t flags,
|
||||
const char *editline_name, // Used for saving history files
|
||||
const char *prompt,
|
||||
bool multi_line,
|
||||
IOHandlerDelegate &delegate);
|
||||
|
||||
virtual
|
||||
~IOHandlerEditline ();
|
||||
|
||||
virtual void
|
||||
Run ();
|
||||
|
||||
virtual void
|
||||
Hide ();
|
||||
|
||||
virtual void
|
||||
Refresh ();
|
||||
|
||||
virtual void
|
||||
Interrupt ();
|
||||
|
||||
virtual void
|
||||
GotEOF();
|
||||
|
||||
virtual void
|
||||
Activate ()
|
||||
{
|
||||
IOHandler::Activate();
|
||||
m_delegate.IOHandlerActivated(*this);
|
||||
}
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
return m_delegate.GetControlSequence (ch);
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetPrompt ();
|
||||
|
||||
virtual bool
|
||||
SetPrompt (const char *prompt);
|
||||
|
||||
bool
|
||||
GetLine (std::string &line);
|
||||
|
||||
bool
|
||||
GetLines (StringList &lines);
|
||||
|
||||
private:
|
||||
static LineStatus
|
||||
LineCompletedCallback (Editline *editline,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error,
|
||||
void *baton);
|
||||
|
||||
static int AutoCompleteCallback (const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches,
|
||||
void *baton);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Editline> m_editline_ap;
|
||||
IOHandlerDelegate &m_delegate;
|
||||
std::string m_prompt;
|
||||
bool m_multi_line;
|
||||
};
|
||||
|
||||
class IOHandlerConfirm :
|
||||
public IOHandlerEditline,
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
IOHandlerConfirm (Debugger &debugger,
|
||||
const char *prompt,
|
||||
bool default_response);
|
||||
|
||||
virtual
|
||||
~IOHandlerConfirm ();
|
||||
|
||||
bool
|
||||
GetResponse () const
|
||||
{
|
||||
return m_user_response;
|
||||
}
|
||||
|
||||
virtual int
|
||||
IOHandlerComplete (IOHandler &io_handler,
|
||||
const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches);
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
|
||||
|
||||
protected:
|
||||
const bool m_default_response;
|
||||
bool m_user_response;
|
||||
};
|
||||
|
||||
class IOHandlerCursesGUI :
|
||||
public IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandlerCursesGUI (Debugger &debugger);
|
||||
|
||||
virtual
|
||||
~IOHandlerCursesGUI ();
|
||||
|
||||
virtual void
|
||||
Run ();
|
||||
|
||||
virtual void
|
||||
Hide ();
|
||||
|
||||
virtual void
|
||||
Refresh ();
|
||||
|
||||
virtual void
|
||||
Interrupt ();
|
||||
|
||||
virtual void
|
||||
GotEOF();
|
||||
|
||||
virtual void
|
||||
Activate ();
|
||||
|
||||
virtual void
|
||||
Deactivate ();
|
||||
|
||||
protected:
|
||||
curses::ApplicationAP m_app_ap;
|
||||
};
|
||||
|
||||
class IOHandlerCursesValueObjectList :
|
||||
public IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandlerCursesValueObjectList (Debugger &debugger, ValueObjectList &valobj_list);
|
||||
|
||||
virtual
|
||||
~IOHandlerCursesValueObjectList ();
|
||||
|
||||
virtual void
|
||||
Run ();
|
||||
|
||||
virtual void
|
||||
Hide ();
|
||||
|
||||
virtual void
|
||||
Refresh ();
|
||||
|
||||
virtual void
|
||||
Interrupt ();
|
||||
|
||||
virtual void
|
||||
GotEOF();
|
||||
protected:
|
||||
ValueObjectList m_valobj_list;
|
||||
};
|
||||
|
||||
class IOHandlerStack
|
||||
{
|
||||
public:
|
||||
|
||||
IOHandlerStack () :
|
||||
m_stack(),
|
||||
m_mutex(Mutex::eMutexTypeRecursive),
|
||||
m_top (NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~IOHandlerStack ()
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
GetSize () const
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
return m_stack.size();
|
||||
}
|
||||
|
||||
void
|
||||
Push (const lldb::IOHandlerSP& sp)
|
||||
{
|
||||
if (sp)
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
m_stack.push (sp);
|
||||
// Set m_top the non-locking IsTop() call
|
||||
m_top = sp.get();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IsEmpty () const
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
return m_stack.empty();
|
||||
}
|
||||
|
||||
lldb::IOHandlerSP
|
||||
Top ()
|
||||
{
|
||||
lldb::IOHandlerSP sp;
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
if (!m_stack.empty())
|
||||
sp = m_stack.top();
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
void
|
||||
Pop ()
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
if (!m_stack.empty())
|
||||
m_stack.pop();
|
||||
// Set m_top the non-locking IsTop() call
|
||||
if (m_stack.empty())
|
||||
m_top = NULL;
|
||||
else
|
||||
m_top = m_stack.top().get();
|
||||
}
|
||||
|
||||
Mutex &
|
||||
GetMutex()
|
||||
{
|
||||
return m_mutex;
|
||||
}
|
||||
|
||||
bool
|
||||
IsTop (const lldb::IOHandlerSP &io_handler_sp) const
|
||||
{
|
||||
return m_top == io_handler_sp.get();
|
||||
}
|
||||
|
||||
ConstString
|
||||
GetTopIOHandlerControlSequence (char ch)
|
||||
{
|
||||
if (m_top)
|
||||
return m_top->GetControlSequence(ch);
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::stack<lldb::IOHandlerSP> m_stack;
|
||||
mutable Mutex m_mutex;
|
||||
IOHandler *m_top;
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (IOHandlerStack);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #ifndef liblldb_IOHandler_h_
|
@ -1,274 +0,0 @@
|
||||
//===-- InputReader.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_InputReader_h_
|
||||
#define liblldb_InputReader_h_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Host/Predicate.h"
|
||||
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class InputReader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t (*Callback) (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
struct HandlerData
|
||||
{
|
||||
InputReader& reader;
|
||||
const char *bytes;
|
||||
size_t bytes_len;
|
||||
void* baton;
|
||||
|
||||
HandlerData(InputReader& r,
|
||||
const char* b,
|
||||
size_t l,
|
||||
void* t) :
|
||||
reader(r),
|
||||
bytes(b),
|
||||
bytes_len(l),
|
||||
baton(t)
|
||||
{
|
||||
}
|
||||
|
||||
lldb::StreamSP
|
||||
GetOutStream();
|
||||
|
||||
bool
|
||||
GetBatchMode();
|
||||
};
|
||||
|
||||
struct InitializationParameters
|
||||
{
|
||||
private:
|
||||
void* m_baton;
|
||||
lldb::InputReaderGranularity m_token_size;
|
||||
char* m_end_token;
|
||||
char* m_prompt;
|
||||
bool m_echo;
|
||||
bool m_save_user_input;
|
||||
public:
|
||||
InitializationParameters() :
|
||||
m_baton(NULL),
|
||||
m_token_size(lldb::eInputReaderGranularityLine),
|
||||
m_echo(true),
|
||||
m_save_user_input(false)
|
||||
{
|
||||
SetEndToken("DONE");
|
||||
SetPrompt("> ");
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetEcho(bool e)
|
||||
{
|
||||
m_echo = e;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetSaveUserInput(bool s)
|
||||
{
|
||||
m_save_user_input = s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetBaton(void* b)
|
||||
{
|
||||
m_baton = b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetGranularity(lldb::InputReaderGranularity g)
|
||||
{
|
||||
m_token_size = g;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetEndToken(const char* e)
|
||||
{
|
||||
m_end_token = new char[strlen(e)+1];
|
||||
::strcpy(m_end_token,e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetPrompt(const char* p)
|
||||
{
|
||||
m_prompt = new char[strlen(p)+1];
|
||||
::strcpy(m_prompt,p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend class InputReaderEZ;
|
||||
|
||||
};
|
||||
|
||||
InputReader (Debugger &debugger);
|
||||
|
||||
virtual
|
||||
~InputReader ();
|
||||
|
||||
virtual Error
|
||||
Initialize (Callback callback,
|
||||
void *baton,
|
||||
lldb::InputReaderGranularity token_size,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo);
|
||||
|
||||
virtual Error Initialize(void* baton,
|
||||
lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
|
||||
const char* end_token = "DONE",
|
||||
const char *prompt = "> ",
|
||||
bool echo = true)
|
||||
{
|
||||
return Error("unimplemented");
|
||||
}
|
||||
|
||||
virtual Error
|
||||
Initialize(InitializationParameters& params)
|
||||
{
|
||||
return Error("unimplemented");
|
||||
}
|
||||
|
||||
// to use these handlers instead of the Callback function, you must subclass
|
||||
// InputReaderEZ, and redefine the handlers for the events you care about
|
||||
virtual void
|
||||
ActivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DeactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
ReactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
AsynchronousOutputWrittenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
GotTokenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
InterruptHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
EOFHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DoneHandler(HandlerData&) {}
|
||||
|
||||
bool
|
||||
IsDone () const
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
void
|
||||
SetIsDone (bool b)
|
||||
{
|
||||
m_done = b;
|
||||
}
|
||||
|
||||
lldb::InputReaderGranularity
|
||||
GetGranularity () const
|
||||
{
|
||||
return m_granularity;
|
||||
}
|
||||
|
||||
bool
|
||||
GetEcho () const
|
||||
{
|
||||
return m_echo;
|
||||
}
|
||||
|
||||
StringList&
|
||||
GetUserInput()
|
||||
{
|
||||
return m_user_input;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GetSaveUserInput()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Subclasses _can_ override this function to get input as it comes in
|
||||
// without any granularity
|
||||
virtual size_t
|
||||
HandleRawBytes (const char *bytes, size_t bytes_len);
|
||||
|
||||
Debugger &
|
||||
GetDebugger()
|
||||
{
|
||||
return m_debugger;
|
||||
}
|
||||
|
||||
bool
|
||||
IsActive () const
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
|
||||
const char *
|
||||
GetPrompt () const;
|
||||
|
||||
void
|
||||
RefreshPrompt();
|
||||
|
||||
// If you want to read from an input reader synchronously, then just initialize the
|
||||
// reader and then call WaitOnReaderIsDone, which will return when the reader is popped.
|
||||
void
|
||||
WaitOnReaderIsDone ();
|
||||
|
||||
static const char *
|
||||
GranularityAsCString (lldb::InputReaderGranularity granularity);
|
||||
|
||||
protected:
|
||||
friend class Debugger;
|
||||
|
||||
void
|
||||
Notify (lldb::InputReaderAction notification);
|
||||
|
||||
Debugger &m_debugger;
|
||||
Callback m_callback;
|
||||
void *m_callback_baton;
|
||||
std::string m_end_token;
|
||||
std::string m_prompt;
|
||||
lldb::InputReaderGranularity m_granularity;
|
||||
bool m_done;
|
||||
bool m_echo;
|
||||
bool m_active;
|
||||
Predicate<bool> m_reader_done;
|
||||
StringList m_user_input;
|
||||
bool m_save_user_input;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReader);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #ifndef liblldb_InputReader_h_
|
@ -1,87 +0,0 @@
|
||||
//===-- InputReaderEZ.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_InputReaderEZ_h_
|
||||
#define liblldb_InputReaderEZ_h_
|
||||
|
||||
#include "lldb/Core/InputReader.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class InputReaderEZ : public InputReader
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
static size_t Callback_Impl(void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
public:
|
||||
|
||||
InputReaderEZ (Debugger &debugger) :
|
||||
InputReader(debugger)
|
||||
{}
|
||||
|
||||
virtual
|
||||
~InputReaderEZ ();
|
||||
|
||||
using InputReader::Initialize;
|
||||
virtual Error
|
||||
Initialize(void* baton,
|
||||
lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
|
||||
const char* end_token = "DONE",
|
||||
const char *prompt = "> ",
|
||||
bool echo = true);
|
||||
|
||||
virtual Error
|
||||
Initialize(InitializationParameters& params);
|
||||
|
||||
virtual void
|
||||
ActivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DeactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
ReactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
AsynchronousOutputWrittenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
GotTokenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
InterruptHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
EOFHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DoneHandler(HandlerData&) {}
|
||||
|
||||
virtual bool
|
||||
GetSaveUserInput()
|
||||
{
|
||||
return m_save_user_input;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class Debugger;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReaderEZ);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #ifndef liblldb_InputReaderEZ_h_
|
@ -1,58 +0,0 @@
|
||||
//===-- InputReaderStack.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_InputReaderStack_h_
|
||||
#define liblldb_InputReaderStack_h_
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class InputReaderStack
|
||||
{
|
||||
public:
|
||||
|
||||
InputReaderStack ();
|
||||
|
||||
~InputReaderStack ();
|
||||
|
||||
size_t
|
||||
GetSize () const;
|
||||
|
||||
void
|
||||
Push (const lldb::InputReaderSP& reader_sp);
|
||||
|
||||
bool
|
||||
IsEmpty () const;
|
||||
|
||||
lldb::InputReaderSP
|
||||
Top ();
|
||||
|
||||
void
|
||||
Pop ();
|
||||
|
||||
Mutex &
|
||||
GetStackMutex ();
|
||||
|
||||
protected:
|
||||
|
||||
std::stack<lldb::InputReaderSP> m_input_readers;
|
||||
mutable Mutex m_input_readers_mutex;
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReaderStack);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_InputReaderStack_h_
|
@ -382,9 +382,9 @@ class MappedHash
|
||||
lldb::offset_t offset = m_header.Read (data, 0);
|
||||
if (offset != LLDB_INVALID_OFFSET && IsValid ())
|
||||
{
|
||||
m_hash_indexes = (uint32_t *)data.GetData (&offset, m_header.bucket_count * sizeof(uint32_t));
|
||||
m_hash_values = (uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t));
|
||||
m_hash_offsets = (uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t));
|
||||
m_hash_indexes = (const uint32_t *)data.GetData (&offset, m_header.bucket_count * sizeof(uint32_t));
|
||||
m_hash_values = (const uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t));
|
||||
m_hash_offsets = (const uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
@ -542,9 +542,9 @@ class MappedHash
|
||||
protected:
|
||||
// Implementation agnostic information
|
||||
HeaderType m_header;
|
||||
uint32_t *m_hash_indexes;
|
||||
uint32_t *m_hash_values;
|
||||
uint32_t *m_hash_offsets;
|
||||
const uint32_t *m_hash_indexes;
|
||||
const uint32_t *m_hash_values;
|
||||
const uint32_t *m_hash_offsets;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -113,10 +113,18 @@ class Module :
|
||||
/// @param[in] target
|
||||
/// The target in which to apply the section load addresses.
|
||||
///
|
||||
/// @param[in] offset
|
||||
/// The offset to apply to all file addresses for all top
|
||||
/// level sections in the object file as each section load
|
||||
/// address is being set.
|
||||
/// @param[in] value
|
||||
/// if \a value_is_offset is true, then value is the offset to
|
||||
/// apply to all file addresses for all top level sections in
|
||||
/// the object file as each section load address is being set.
|
||||
/// If \a value_is_offset is false, then "value" is the new
|
||||
/// absolute base address for the image.
|
||||
///
|
||||
/// @param[in] value_is_offset
|
||||
/// If \b true, then \a value is an offset to apply to each
|
||||
/// file address of each top level section.
|
||||
/// If \b false, then \a value is the image base address that
|
||||
/// will be used to rigidly slide all loadable sections.
|
||||
///
|
||||
/// @param[out] changed
|
||||
/// If any section load addresses were changed in \a target,
|
||||
@ -133,7 +141,8 @@ class Module :
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
SetLoadAddress (Target &target,
|
||||
lldb::addr_t offset,
|
||||
lldb::addr_t value,
|
||||
bool value_is_offset,
|
||||
bool &changed);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -15,7 +15,9 @@
|
||||
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
// Project includes
|
||||
#include "lldb/Host/Endian.h"
|
||||
#include "lldb/lldb-public.h"
|
||||
|
||||
namespace lldb
|
||||
@ -39,31 +41,31 @@ namespace lldb_private {
|
||||
eTypeBytes
|
||||
};
|
||||
|
||||
Opcode () : m_type (eTypeInvalid)
|
||||
Opcode () : m_byte_order (lldb::eByteOrderInvalid), m_type (eTypeInvalid)
|
||||
{
|
||||
}
|
||||
|
||||
Opcode (uint8_t inst) : m_type (eType8)
|
||||
Opcode (uint8_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType8)
|
||||
{
|
||||
m_data.inst8 = inst;
|
||||
}
|
||||
|
||||
Opcode (uint16_t inst) : m_type (eType16)
|
||||
Opcode (uint16_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType16)
|
||||
{
|
||||
m_data.inst16 = inst;
|
||||
}
|
||||
|
||||
Opcode (uint32_t inst) : m_type (eType32)
|
||||
Opcode (uint32_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType32)
|
||||
{
|
||||
m_data.inst32 = inst;
|
||||
}
|
||||
|
||||
Opcode (uint64_t inst) : m_type (eType64)
|
||||
Opcode (uint64_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType64)
|
||||
{
|
||||
m_data.inst64 = inst;
|
||||
}
|
||||
|
||||
Opcode (uint8_t *bytes, size_t length)
|
||||
Opcode (uint8_t *bytes, size_t length) : m_byte_order (lldb::eByteOrderInvalid)
|
||||
{
|
||||
SetOpcodeBytes (bytes, length);
|
||||
}
|
||||
@ -71,6 +73,7 @@ namespace lldb_private {
|
||||
void
|
||||
Clear()
|
||||
{
|
||||
m_byte_order = lldb::eByteOrderInvalid;
|
||||
m_type = Opcode::eTypeInvalid;
|
||||
}
|
||||
Opcode::Type
|
||||
@ -102,7 +105,7 @@ namespace lldb_private {
|
||||
{
|
||||
case Opcode::eTypeInvalid: break;
|
||||
case Opcode::eType8: return m_data.inst8;
|
||||
case Opcode::eType16: return m_data.inst16;
|
||||
case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
|
||||
case Opcode::eType16_2: break;
|
||||
case Opcode::eType32: break;
|
||||
case Opcode::eType64: break;
|
||||
@ -118,9 +121,9 @@ namespace lldb_private {
|
||||
{
|
||||
case Opcode::eTypeInvalid: break;
|
||||
case Opcode::eType8: return m_data.inst8;
|
||||
case Opcode::eType16: return m_data.inst16;
|
||||
case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
|
||||
case Opcode::eType16_2: // passthrough
|
||||
case Opcode::eType32: return m_data.inst32;
|
||||
case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
|
||||
case Opcode::eType64: break;
|
||||
case Opcode::eTypeBytes: break;
|
||||
}
|
||||
@ -134,48 +137,53 @@ namespace lldb_private {
|
||||
{
|
||||
case Opcode::eTypeInvalid: break;
|
||||
case Opcode::eType8: return m_data.inst8;
|
||||
case Opcode::eType16: return m_data.inst16;
|
||||
case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
|
||||
case Opcode::eType16_2: // passthrough
|
||||
case Opcode::eType32: return m_data.inst32;
|
||||
case Opcode::eType64: return m_data.inst64;
|
||||
case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
|
||||
case Opcode::eType64: return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64;
|
||||
case Opcode::eTypeBytes: break;
|
||||
}
|
||||
return invalid_opcode;
|
||||
}
|
||||
|
||||
void
|
||||
SetOpcode8 (uint8_t inst)
|
||||
SetOpcode8 (uint8_t inst, lldb::ByteOrder order)
|
||||
{
|
||||
m_type = eType8;
|
||||
m_data.inst8 = inst;
|
||||
m_byte_order = order;
|
||||
}
|
||||
|
||||
void
|
||||
SetOpcode16 (uint16_t inst)
|
||||
SetOpcode16 (uint16_t inst, lldb::ByteOrder order)
|
||||
{
|
||||
m_type = eType16;
|
||||
m_data.inst16 = inst;
|
||||
m_byte_order = order;
|
||||
}
|
||||
|
||||
void
|
||||
SetOpcode16_2 (uint32_t inst)
|
||||
SetOpcode16_2 (uint32_t inst, lldb::ByteOrder order)
|
||||
{
|
||||
m_type = eType16_2;
|
||||
m_data.inst32 = inst;
|
||||
m_byte_order = order;
|
||||
}
|
||||
|
||||
void
|
||||
SetOpcode32 (uint32_t inst)
|
||||
SetOpcode32 (uint32_t inst, lldb::ByteOrder order)
|
||||
{
|
||||
m_type = eType32;
|
||||
m_data.inst32 = inst;
|
||||
m_byte_order = order;
|
||||
}
|
||||
|
||||
void
|
||||
SetOpcode64 (uint64_t inst)
|
||||
SetOpcode64 (uint64_t inst, lldb::ByteOrder order)
|
||||
{
|
||||
m_type = eType64;
|
||||
m_data.inst64 = inst;
|
||||
m_byte_order = order;
|
||||
}
|
||||
|
||||
void
|
||||
@ -187,6 +195,7 @@ namespace lldb_private {
|
||||
m_data.inst.length = length;
|
||||
assert (length < sizeof (m_data.inst.bytes));
|
||||
memcpy (m_data.inst.bytes, bytes, length);
|
||||
m_byte_order = lldb::eByteOrderInvalid;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -249,6 +258,15 @@ namespace lldb_private {
|
||||
lldb::ByteOrder
|
||||
GetDataByteOrder () const;
|
||||
|
||||
bool
|
||||
GetEndianSwap() const
|
||||
{
|
||||
return (m_byte_order == lldb::eByteOrderBig && lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle) ||
|
||||
(m_byte_order == lldb::eByteOrderLittle && lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig);
|
||||
}
|
||||
|
||||
lldb::ByteOrder m_byte_order;
|
||||
|
||||
Opcode::Type m_type;
|
||||
union
|
||||
{
|
||||
|
@ -70,6 +70,15 @@ class SourceManager
|
||||
return m_source_map_mod_id;
|
||||
}
|
||||
|
||||
const char *
|
||||
PeekLineData (uint32_t line);
|
||||
|
||||
uint32_t
|
||||
GetLineLength (uint32_t line, bool include_newline_chars);
|
||||
|
||||
uint32_t
|
||||
GetNumLines ();
|
||||
|
||||
protected:
|
||||
|
||||
bool
|
||||
@ -167,11 +176,11 @@ class SourceManager
|
||||
uint32_t start_line,
|
||||
uint32_t end_line,
|
||||
std::vector<uint32_t> &match_lines);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
FileSP
|
||||
GetFile (const FileSpec &file_spec);
|
||||
|
||||
protected:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from SourceManager can see and modify these
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
@ -35,7 +34,7 @@ class StreamAsynchronousIO :
|
||||
private:
|
||||
Broadcaster &m_broadcaster;
|
||||
uint32_t m_broadcast_event_type;
|
||||
StreamString m_accumulated_data;
|
||||
std::string m_accumulated_data;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
@ -33,6 +33,9 @@ class StringList
|
||||
void
|
||||
AppendString (const std::string &s);
|
||||
|
||||
void
|
||||
AppendString (std::string &&s);
|
||||
|
||||
void
|
||||
AppendString (const char *str);
|
||||
|
||||
@ -51,6 +54,34 @@ class StringList
|
||||
size_t
|
||||
GetSize () const;
|
||||
|
||||
void
|
||||
SetSize (size_t n)
|
||||
{
|
||||
m_strings.resize(n);
|
||||
}
|
||||
|
||||
size_t
|
||||
GetMaxStringLength () const;
|
||||
|
||||
std::string &
|
||||
operator [](size_t idx)
|
||||
{
|
||||
// No bounds checking, verify "idx" is good prior to calling this function
|
||||
return m_strings[idx];
|
||||
}
|
||||
|
||||
const std::string &
|
||||
operator [](size_t idx) const
|
||||
{
|
||||
// No bounds checking, verify "idx" is good prior to calling this function
|
||||
return m_strings[idx];
|
||||
}
|
||||
|
||||
void
|
||||
PopBack ()
|
||||
{
|
||||
m_strings.pop_back();
|
||||
}
|
||||
const char *
|
||||
GetStringAtIndex (size_t idx) const;
|
||||
|
||||
@ -63,6 +94,12 @@ class StringList
|
||||
void
|
||||
LongestCommonPrefix (std::string &common_prefix);
|
||||
|
||||
void
|
||||
InsertStringAtIndex (size_t idx, const std::string &str);
|
||||
|
||||
void
|
||||
InsertStringAtIndex (size_t idx, std::string &&str);
|
||||
|
||||
void
|
||||
InsertStringAtIndex (size_t id, const char *str);
|
||||
|
||||
@ -72,12 +109,15 @@ class StringList
|
||||
void
|
||||
RemoveBlankLines ();
|
||||
|
||||
size_t
|
||||
SplitIntoLines (const std::string &lines);
|
||||
|
||||
size_t
|
||||
SplitIntoLines (const char *lines, size_t len);
|
||||
|
||||
std::string
|
||||
CopyList(const char* item_preamble = NULL,
|
||||
const char* items_sep = "\n");
|
||||
const char* items_sep = "\n") const;
|
||||
|
||||
StringList&
|
||||
operator << (const char* str);
|
||||
|
@ -499,6 +499,10 @@ class ValueObject : public UserID
|
||||
GetValueAsCString ();
|
||||
|
||||
virtual bool
|
||||
GetValueAsCString (const lldb_private::TypeFormatImpl& format,
|
||||
std::string& destination);
|
||||
|
||||
bool
|
||||
GetValueAsCString (lldb::Format format,
|
||||
std::string& destination);
|
||||
|
||||
@ -615,7 +619,8 @@ class ValueObject : public UserID
|
||||
DumpPrintableRepresentation (Stream& s,
|
||||
ValueObjectRepresentationStyle val_obj_display = eValueObjectRepresentationStyleSummary,
|
||||
lldb::Format custom_format = lldb::eFormatInvalid,
|
||||
PrintableRepresentationSpecialCases special = ePrintableRepresentationSpecialCasesAllow);
|
||||
PrintableRepresentationSpecialCases special = ePrintableRepresentationSpecialCasesAllow,
|
||||
bool do_dump_error = true);
|
||||
bool
|
||||
GetValueIsValid () const;
|
||||
|
||||
|
@ -75,6 +75,12 @@ class ValueObjectList
|
||||
void
|
||||
Swap (ValueObjectList &value_object_list);
|
||||
|
||||
void
|
||||
Clear ()
|
||||
{
|
||||
m_value_objects.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::vector<lldb::ValueObjectSP> collection;
|
||||
//------------------------------------------------------------------
|
||||
|
@ -79,6 +79,9 @@ namespace lldb_private {
|
||||
|
||||
bool
|
||||
LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::wstring
|
||||
|
||||
bool
|
||||
LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::shared_ptr<> and std::weak_ptr<>
|
||||
|
||||
bool
|
||||
ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream);
|
||||
@ -594,10 +597,11 @@ namespace lldb_private {
|
||||
virtual
|
||||
~LibcxxVectorBoolSyntheticFrontEnd ();
|
||||
private:
|
||||
ClangASTType m_bool_type;
|
||||
ExecutionContextRef m_exe_ctx_ref;
|
||||
uint64_t m_count;
|
||||
lldb::addr_t m_base_data_address;
|
||||
EvaluateExpressionOptions m_options;
|
||||
std::map<size_t,lldb::ValueObjectSP> m_children;
|
||||
};
|
||||
|
||||
SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "lldb/DataFormatters/FormatCache.h"
|
||||
#include "lldb/DataFormatters/FormatClasses.h"
|
||||
#include "lldb/DataFormatters/FormatNavigator.h"
|
||||
#include "lldb/DataFormatters/FormattersContainer.h"
|
||||
#include "lldb/DataFormatters/TypeCategory.h"
|
||||
#include "lldb/DataFormatters/TypeCategoryMap.h"
|
||||
|
||||
@ -44,7 +44,7 @@ class FormatManager : public IFormatChangeListener
|
||||
FormatManager ();
|
||||
|
||||
NamedSummariesMap&
|
||||
GetNamedSummaryNavigator ()
|
||||
GetNamedSummaryContainer ()
|
||||
{
|
||||
return m_named_summaries_map;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- FormatNavigator.h ----------------------------------------*- C++ -*-===//
|
||||
//===-- FormattersContainer.h ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,8 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef lldb_FormatNavigator_h_
|
||||
#define lldb_FormatNavigator_h_
|
||||
#ifndef lldb_FormattersContainer_h_
|
||||
#define lldb_FormattersContainer_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
@ -104,7 +104,7 @@ GetValidTypeName_Impl (const ConstString& type)
|
||||
}
|
||||
|
||||
template<typename KeyType, typename ValueType>
|
||||
class FormatNavigator;
|
||||
class FormattersContainer;
|
||||
|
||||
template<typename KeyType, typename ValueType>
|
||||
class FormatMap
|
||||
@ -243,13 +243,13 @@ class FormatMap
|
||||
return m_map_mutex;
|
||||
}
|
||||
|
||||
friend class FormatNavigator<KeyType, ValueType>;
|
||||
friend class FormattersContainer<KeyType, ValueType>;
|
||||
friend class FormatManager;
|
||||
|
||||
};
|
||||
|
||||
template<typename KeyType, typename ValueType>
|
||||
class FormatNavigator
|
||||
class FormattersContainer
|
||||
{
|
||||
protected:
|
||||
typedef FormatMap<KeyType,ValueType> BackEndType;
|
||||
@ -260,11 +260,11 @@ class FormatNavigator
|
||||
typedef typename MapType::key_type MapKeyType;
|
||||
typedef typename MapType::mapped_type MapValueType;
|
||||
typedef typename BackEndType::CallbackType CallbackType;
|
||||
typedef typename std::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer;
|
||||
typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType> > SharedPointer;
|
||||
|
||||
friend class TypeCategoryImpl;
|
||||
|
||||
FormatNavigator(std::string name,
|
||||
FormattersContainer(std::string name,
|
||||
IFormatChangeListener* lst) :
|
||||
m_format_map(lst),
|
||||
m_name(name),
|
||||
@ -350,7 +350,7 @@ class FormatNavigator
|
||||
|
||||
std::string m_name;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
|
||||
DISALLOW_COPY_AND_ASSIGN(FormattersContainer);
|
||||
|
||||
ConstString m_id_cs;
|
||||
|
||||
@ -470,6 +470,7 @@ class FormatNavigator
|
||||
{
|
||||
for (const FormattersMatchCandidate& candidate : candidates)
|
||||
{
|
||||
// FIXME: could we do the IsMatch() check first?
|
||||
if (Get(candidate.GetTypeName(),entry))
|
||||
{
|
||||
if (candidate.IsMatch(entry) == false)
|
||||
@ -491,4 +492,4 @@ class FormatNavigator
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // lldb_FormatNavigator_h_
|
||||
#endif // lldb_FormattersContainer_h_
|
@ -19,108 +19,131 @@
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#include "lldb/DataFormatters/FormatClasses.h"
|
||||
#include "lldb/DataFormatters/FormatNavigator.h"
|
||||
#include "lldb/DataFormatters/FormattersContainer.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
template <typename FormatterImpl>
|
||||
class FormatterContainerPair
|
||||
{
|
||||
public:
|
||||
typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer;
|
||||
typedef FormattersContainer<lldb::RegularExpressionSP, FormatterImpl> RegexMatchContainer;
|
||||
|
||||
typedef typename ExactMatchContainer::MapType ExactMatchMap;
|
||||
typedef typename RegexMatchContainer::MapType RegexMatchMap;
|
||||
|
||||
typedef typename ExactMatchContainer::MapValueType MapValueType;
|
||||
|
||||
typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP;
|
||||
typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP;
|
||||
|
||||
FormatterContainerPair (const char* exact_name,
|
||||
const char* regex_name,
|
||||
IFormatChangeListener* clist) :
|
||||
m_exact_sp(new ExactMatchContainer(std::string(exact_name),clist)),
|
||||
m_regex_sp(new RegexMatchContainer(std::string(regex_name),clist))
|
||||
{
|
||||
}
|
||||
|
||||
~FormatterContainerPair () = default;
|
||||
|
||||
ExactMatchContainerSP
|
||||
GetExactMatch () const
|
||||
{
|
||||
return m_exact_sp;
|
||||
}
|
||||
|
||||
RegexMatchContainerSP
|
||||
GetRegexMatch () const
|
||||
{
|
||||
return m_regex_sp;
|
||||
}
|
||||
|
||||
private:
|
||||
ExactMatchContainerSP m_exact_sp;
|
||||
RegexMatchContainerSP m_regex_sp;
|
||||
};
|
||||
|
||||
namespace lldb_private {
|
||||
class TypeCategoryImpl
|
||||
{
|
||||
private:
|
||||
typedef FormatNavigator<ConstString, TypeFormatImpl> ValueNavigator;
|
||||
typedef FormatNavigator<lldb::RegularExpressionSP, TypeFormatImpl> RegexValueNavigator;
|
||||
|
||||
typedef FormatNavigator<ConstString, TypeSummaryImpl> SummaryNavigator;
|
||||
typedef FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl> RegexSummaryNavigator;
|
||||
|
||||
typedef FormatNavigator<ConstString, TypeFilterImpl> FilterNavigator;
|
||||
typedef FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl> RegexFilterNavigator;
|
||||
typedef FormatterContainerPair<TypeFormatImpl> FormatContainer;
|
||||
typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer;
|
||||
typedef FormatterContainerPair<TypeFilterImpl> FilterContainer;
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
typedef FormatNavigator<ConstString, ScriptedSyntheticChildren> SynthNavigator;
|
||||
typedef FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren> RegexSynthNavigator;
|
||||
typedef FormatterContainerPair<ScriptedSyntheticChildren> SynthContainer;
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
|
||||
typedef ValueNavigator::MapType ValueMap;
|
||||
typedef RegexValueNavigator::MapType RegexValueMap;
|
||||
|
||||
typedef SummaryNavigator::MapType SummaryMap;
|
||||
typedef RegexSummaryNavigator::MapType RegexSummaryMap;
|
||||
|
||||
typedef FilterNavigator::MapType FilterMap;
|
||||
typedef RegexFilterNavigator::MapType RegexFilterMap;
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
typedef SynthNavigator::MapType SynthMap;
|
||||
typedef RegexSynthNavigator::MapType RegexSynthMap;
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
|
||||
public:
|
||||
|
||||
typedef uint16_t FormatCategoryItems;
|
||||
static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
|
||||
|
||||
typedef ValueNavigator::SharedPointer ValueNavigatorSP;
|
||||
typedef RegexValueNavigator::SharedPointer RegexValueNavigatorSP;
|
||||
typedef FormatContainer::ExactMatchContainerSP FormatContainerSP;
|
||||
typedef FormatContainer::RegexMatchContainerSP RegexFormatContainerSP;
|
||||
|
||||
typedef SummaryNavigator::SharedPointer SummaryNavigatorSP;
|
||||
typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP;
|
||||
typedef SummaryContainer::ExactMatchContainerSP SummaryContainerSP;
|
||||
typedef SummaryContainer::RegexMatchContainerSP RegexSummaryContainerSP;
|
||||
|
||||
typedef FilterNavigator::SharedPointer FilterNavigatorSP;
|
||||
typedef RegexFilterNavigator::SharedPointer RegexFilterNavigatorSP;
|
||||
typedef FilterContainer::ExactMatchContainerSP FilterContainerSP;
|
||||
typedef FilterContainer::RegexMatchContainerSP RegexFilterContainerSP;
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
typedef SynthNavigator::SharedPointer SynthNavigatorSP;
|
||||
typedef RegexSynthNavigator::SharedPointer RegexSynthNavigatorSP;
|
||||
typedef SynthContainer::ExactMatchContainerSP SynthContainerSP;
|
||||
typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP;
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
|
||||
TypeCategoryImpl (IFormatChangeListener* clist,
|
||||
ConstString name);
|
||||
|
||||
ValueNavigatorSP
|
||||
GetValueNavigator ()
|
||||
FormatContainerSP
|
||||
GetTypeFormatsContainer ()
|
||||
{
|
||||
return ValueNavigatorSP(m_value_nav);
|
||||
return m_format_cont.GetExactMatch();
|
||||
}
|
||||
|
||||
RegexValueNavigatorSP
|
||||
GetRegexValueNavigator ()
|
||||
RegexFormatContainerSP
|
||||
GetRegexTypeFormatsContainer ()
|
||||
{
|
||||
return RegexValueNavigatorSP(m_regex_value_nav);
|
||||
return m_format_cont.GetRegexMatch();
|
||||
}
|
||||
|
||||
SummaryNavigatorSP
|
||||
GetSummaryNavigator ()
|
||||
SummaryContainerSP
|
||||
GetTypeSummariesContainer ()
|
||||
{
|
||||
return SummaryNavigatorSP(m_summary_nav);
|
||||
return m_summary_cont.GetExactMatch();
|
||||
}
|
||||
|
||||
RegexSummaryNavigatorSP
|
||||
GetRegexSummaryNavigator ()
|
||||
RegexSummaryContainerSP
|
||||
GetRegexTypeSummariesContainer ()
|
||||
{
|
||||
return RegexSummaryNavigatorSP(m_regex_summary_nav);
|
||||
return m_summary_cont.GetRegexMatch();
|
||||
}
|
||||
|
||||
FilterNavigatorSP
|
||||
GetFilterNavigator ()
|
||||
FilterContainerSP
|
||||
GetTypeFiltersContainer ()
|
||||
{
|
||||
return FilterNavigatorSP(m_filter_nav);
|
||||
return m_filter_cont.GetExactMatch();
|
||||
}
|
||||
|
||||
RegexFilterNavigatorSP
|
||||
GetRegexFilterNavigator ()
|
||||
RegexFilterContainerSP
|
||||
GetRegexTypeFiltersContainer ()
|
||||
{
|
||||
return RegexFilterNavigatorSP(m_regex_filter_nav);
|
||||
return m_filter_cont.GetRegexMatch();
|
||||
}
|
||||
|
||||
ValueNavigator::MapValueType
|
||||
FormatContainer::MapValueType
|
||||
GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
SummaryNavigator::MapValueType
|
||||
SummaryContainer::MapValueType
|
||||
GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
FilterNavigator::MapValueType
|
||||
FilterContainer::MapValueType
|
||||
GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
SynthNavigator::MapValueType
|
||||
SynthContainer::MapValueType
|
||||
GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
#endif
|
||||
|
||||
@ -130,32 +153,32 @@ namespace lldb_private {
|
||||
lldb::TypeNameSpecifierImplSP
|
||||
GetTypeNameSpecifierForSummaryAtIndex (size_t index);
|
||||
|
||||
ValueNavigator::MapValueType
|
||||
FormatContainer::MapValueType
|
||||
GetFormatAtIndex (size_t index);
|
||||
|
||||
SummaryNavigator::MapValueType
|
||||
SummaryContainer::MapValueType
|
||||
GetSummaryAtIndex (size_t index);
|
||||
|
||||
FilterNavigator::MapValueType
|
||||
FilterContainer::MapValueType
|
||||
GetFilterAtIndex (size_t index);
|
||||
|
||||
lldb::TypeNameSpecifierImplSP
|
||||
GetTypeNameSpecifierForFilterAtIndex (size_t index);
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
SynthNavigatorSP
|
||||
GetSyntheticNavigator ()
|
||||
SynthContainerSP
|
||||
GetTypeSyntheticsContainer ()
|
||||
{
|
||||
return SynthNavigatorSP(m_synth_nav);
|
||||
return m_synth_cont.GetExactMatch();
|
||||
}
|
||||
|
||||
RegexSynthNavigatorSP
|
||||
GetRegexSyntheticNavigator ()
|
||||
RegexSynthContainerSP
|
||||
GetRegexTypeSyntheticsContainer ()
|
||||
{
|
||||
return RegexSynthNavigatorSP(m_regex_synth_nav);
|
||||
return m_synth_cont.GetRegexMatch();
|
||||
}
|
||||
|
||||
SynthNavigator::MapValueType
|
||||
SynthContainer::MapValueType
|
||||
GetSyntheticAtIndex (size_t index);
|
||||
|
||||
lldb::TypeNameSpecifierImplSP
|
||||
@ -222,18 +245,14 @@ namespace lldb_private {
|
||||
typedef std::shared_ptr<TypeCategoryImpl> SharedPointer;
|
||||
|
||||
private:
|
||||
ValueNavigator::SharedPointer m_value_nav;
|
||||
RegexValueNavigator::SharedPointer m_regex_value_nav;
|
||||
FormatContainer m_format_cont;
|
||||
|
||||
SummaryNavigator::SharedPointer m_summary_nav;
|
||||
RegexSummaryNavigator::SharedPointer m_regex_summary_nav;
|
||||
SummaryContainer m_summary_cont;
|
||||
|
||||
FilterNavigator::SharedPointer m_filter_nav;
|
||||
RegexFilterNavigator::SharedPointer m_regex_filter_nav;
|
||||
FilterContainer m_filter_cont;
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
SynthNavigator::SharedPointer m_synth_nav;
|
||||
RegexSynthNavigator::SharedPointer m_regex_synth_nav;
|
||||
SynthContainer m_synth_cont;
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
|
||||
bool m_enabled;
|
||||
@ -257,18 +276,18 @@ namespace lldb_private {
|
||||
|
||||
friend class TypeCategoryMap;
|
||||
|
||||
friend class FormatNavigator<ConstString, TypeFormatImpl>;
|
||||
friend class FormatNavigator<lldb::RegularExpressionSP, TypeFormatImpl>;
|
||||
friend class FormattersContainer<ConstString, TypeFormatImpl>;
|
||||
friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>;
|
||||
|
||||
friend class FormatNavigator<ConstString, TypeSummaryImpl>;
|
||||
friend class FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl>;
|
||||
friend class FormattersContainer<ConstString, TypeSummaryImpl>;
|
||||
friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>;
|
||||
|
||||
friend class FormatNavigator<ConstString, TypeFilterImpl>;
|
||||
friend class FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl>;
|
||||
friend class FormattersContainer<ConstString, TypeFilterImpl>;
|
||||
friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>;
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
friend class FormatNavigator<ConstString, ScriptedSyntheticChildren>;
|
||||
friend class FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren>;
|
||||
friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>;
|
||||
friend class FormattersContainer<lldb::RegularExpressionSP, ScriptedSyntheticChildren>;
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#include "lldb/DataFormatters/FormatNavigator.h"
|
||||
#include "lldb/DataFormatters/FormattersContainer.h"
|
||||
#include "lldb/DataFormatters/TypeCategory.h"
|
||||
|
||||
namespace lldb_private {
|
||||
@ -144,7 +144,7 @@ namespace lldb_private {
|
||||
return m_map_mutex;
|
||||
}
|
||||
|
||||
friend class FormatNavigator<KeyType, ValueType>;
|
||||
friend class FormattersContainer<KeyType, ValueType>;
|
||||
friend class FormatManager;
|
||||
};
|
||||
} // namespace lldb_private
|
||||
|
@ -130,15 +130,12 @@ namespace lldb_private {
|
||||
uint32_t m_flags;
|
||||
};
|
||||
|
||||
TypeFormatImpl (lldb::Format f = lldb::eFormatInvalid,
|
||||
const Flags& flags = Flags());
|
||||
TypeFormatImpl (const Flags& flags = Flags());
|
||||
|
||||
typedef std::shared_ptr<TypeFormatImpl> SharedPointer;
|
||||
typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&);
|
||||
|
||||
~TypeFormatImpl ()
|
||||
{
|
||||
}
|
||||
virtual ~TypeFormatImpl () = default;
|
||||
|
||||
bool
|
||||
Cascades () const
|
||||
@ -173,19 +170,7 @@ namespace lldb_private {
|
||||
{
|
||||
m_flags.SetSkipReferences(value);
|
||||
}
|
||||
|
||||
lldb::Format
|
||||
GetFormat () const
|
||||
{
|
||||
return m_format;
|
||||
}
|
||||
|
||||
void
|
||||
SetFormat (lldb::Format fmt)
|
||||
{
|
||||
m_format = fmt;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
GetOptions ()
|
||||
{
|
||||
@ -204,17 +189,123 @@ namespace lldb_private {
|
||||
return m_my_revision;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription();
|
||||
enum class Type
|
||||
{
|
||||
eTypeUnknown,
|
||||
eTypeFormat,
|
||||
eTypeEnum
|
||||
};
|
||||
|
||||
virtual Type
|
||||
GetType ()
|
||||
{
|
||||
return Type::eTypeUnknown;
|
||||
}
|
||||
|
||||
// we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
|
||||
// extended periods of time and we trust the ValueObject to stay around for as long as it is required
|
||||
// for us to generate its value
|
||||
virtual bool
|
||||
FormatObject (ValueObject *valobj,
|
||||
std::string& dest) const = 0;
|
||||
|
||||
virtual std::string
|
||||
GetDescription() = 0;
|
||||
|
||||
protected:
|
||||
Flags m_flags;
|
||||
lldb::Format m_format;
|
||||
uint32_t m_my_revision;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
|
||||
};
|
||||
};
|
||||
|
||||
class TypeFormatImpl_Format : public TypeFormatImpl
|
||||
{
|
||||
public:
|
||||
TypeFormatImpl_Format (lldb::Format f = lldb::eFormatInvalid,
|
||||
const TypeFormatImpl::Flags& flags = Flags());
|
||||
|
||||
typedef std::shared_ptr<TypeFormatImpl_Format> SharedPointer;
|
||||
typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_Format::SharedPointer&);
|
||||
|
||||
virtual ~TypeFormatImpl_Format () = default;
|
||||
|
||||
lldb::Format
|
||||
GetFormat () const
|
||||
{
|
||||
return m_format;
|
||||
}
|
||||
|
||||
void
|
||||
SetFormat (lldb::Format fmt)
|
||||
{
|
||||
m_format = fmt;
|
||||
}
|
||||
|
||||
virtual TypeFormatImpl::Type
|
||||
GetType ()
|
||||
{
|
||||
return TypeFormatImpl::Type::eTypeFormat;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
FormatObject (ValueObject *valobj,
|
||||
std::string& dest) const;
|
||||
|
||||
virtual std::string
|
||||
GetDescription();
|
||||
|
||||
protected:
|
||||
lldb::Format m_format;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_Format);
|
||||
};
|
||||
|
||||
class TypeFormatImpl_EnumType : public TypeFormatImpl
|
||||
{
|
||||
public:
|
||||
TypeFormatImpl_EnumType (ConstString type_name = ConstString(""),
|
||||
const TypeFormatImpl::Flags& flags = Flags());
|
||||
|
||||
typedef std::shared_ptr<TypeFormatImpl_EnumType> SharedPointer;
|
||||
typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_EnumType::SharedPointer&);
|
||||
|
||||
~TypeFormatImpl_EnumType () = default;
|
||||
|
||||
ConstString
|
||||
GetTypeName ()
|
||||
{
|
||||
return m_enum_type;
|
||||
}
|
||||
|
||||
void
|
||||
SetTypeName (ConstString enum_type)
|
||||
{
|
||||
m_enum_type = enum_type;
|
||||
}
|
||||
|
||||
virtual TypeFormatImpl::Type
|
||||
GetType ()
|
||||
{
|
||||
return TypeFormatImpl::Type::eTypeEnum;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
FormatObject (ValueObject *valobj,
|
||||
std::string& dest) const;
|
||||
|
||||
virtual std::string
|
||||
GetDescription();
|
||||
|
||||
protected:
|
||||
ConstString m_enum_type;
|
||||
mutable std::map<void*,ClangASTType> m_types;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_EnumType);
|
||||
};
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // lldb_TypeFormat_h_
|
||||
|
@ -32,10 +32,24 @@ namespace lldb_private {
|
||||
{
|
||||
protected:
|
||||
ValueObject &m_backend;
|
||||
|
||||
void
|
||||
SetValid (bool valid)
|
||||
{
|
||||
m_valid = valid;
|
||||
}
|
||||
|
||||
bool
|
||||
IsValid ()
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
SyntheticChildrenFrontEnd (ValueObject &backend) :
|
||||
m_backend(backend)
|
||||
m_backend(backend),
|
||||
m_valid(true)
|
||||
{}
|
||||
|
||||
virtual
|
||||
@ -71,6 +85,7 @@ namespace lldb_private {
|
||||
typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
|
||||
|
||||
private:
|
||||
bool m_valid;
|
||||
DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
|
||||
};
|
||||
|
||||
|
@ -265,9 +265,6 @@ class ValueObjectPrinter
|
||||
bool
|
||||
PrintValueObject ();
|
||||
|
||||
bool
|
||||
PrintChildrenOneLiner (bool hide_names);
|
||||
|
||||
protected:
|
||||
|
||||
// only this class (and subclasses, if any) should ever be concerned with
|
||||
@ -366,6 +363,9 @@ class ValueObjectPrinter
|
||||
PrintChildrenIfNeeded (bool value_printed,
|
||||
bool summary_printed);
|
||||
|
||||
bool
|
||||
PrintChildrenOneLiner (bool hide_names);
|
||||
|
||||
private:
|
||||
|
||||
ValueObject *m_orig_valobj;
|
||||
@ -386,6 +386,8 @@ class ValueObjectPrinter
|
||||
std::string m_summary;
|
||||
std::string m_error;
|
||||
|
||||
friend class StringSummaryFormat;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter);
|
||||
};
|
||||
|
||||
|
@ -300,7 +300,7 @@ class ClangFunction : public ClangExpression
|
||||
/// @param[in] args_addr
|
||||
/// The address of the argument struct.
|
||||
///
|
||||
/// @param[in] ret_value
|
||||
/// @param[out] ret_value
|
||||
/// The value returned by the function.
|
||||
///
|
||||
/// @return
|
||||
|
@ -30,6 +30,7 @@ namespace llvm {
|
||||
class GlobalValue;
|
||||
class GlobalVariable;
|
||||
class Instruction;
|
||||
class IntegerType;
|
||||
class Module;
|
||||
class StoreInst;
|
||||
class DataLayout;
|
||||
@ -650,6 +651,7 @@ class IRForTarget : public llvm::ModulePass
|
||||
StaticDataAllocator m_data_allocator; ///< The allocator to use for constant strings
|
||||
llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type
|
||||
llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type
|
||||
llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
|
||||
lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed
|
||||
|
||||
llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL.
|
||||
|
209
include/lldb/Host/Editline.h
Normal file
209
include/lldb/Host/Editline.h
Normal file
@ -0,0 +1,209 @@
|
||||
//===-- Editline.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_Editline_h_
|
||||
#define liblldb_Editline_h_
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include "lldb/Host/windows/editlinewin.h"
|
||||
#else
|
||||
#include <histedit.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/Host/Condition.h"
|
||||
#include "lldb/Host/FileSpec.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Editline Editline.h "lldb/Host/Editline.h"
|
||||
/// @brief A class that encapsulates editline functionality.
|
||||
//----------------------------------------------------------------------
|
||||
class Editline
|
||||
{
|
||||
public:
|
||||
typedef LineStatus (*LineCompletedCallbackType) (
|
||||
Editline *editline,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error,
|
||||
void *baton);
|
||||
|
||||
typedef int (*CompleteCallbackType) (
|
||||
const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches,
|
||||
void *baton);
|
||||
|
||||
typedef int (*GetCharCallbackType) (
|
||||
::EditLine *,
|
||||
char *c);
|
||||
|
||||
Editline(const char *prog, // Used for the history file and for editrc program name
|
||||
const char *prompt,
|
||||
FILE *fin,
|
||||
FILE *fout,
|
||||
FILE *ferr);
|
||||
|
||||
~Editline();
|
||||
|
||||
Error
|
||||
GetLine (std::string &line);
|
||||
|
||||
Error
|
||||
GetLines (const std::string &end_line, StringList &lines);
|
||||
|
||||
bool
|
||||
LoadHistory ();
|
||||
|
||||
bool
|
||||
SaveHistory ();
|
||||
|
||||
FILE *
|
||||
GetInputFile ();
|
||||
|
||||
FILE *
|
||||
GetOutputFile ();
|
||||
|
||||
FILE *
|
||||
GetErrorFile ();
|
||||
|
||||
bool
|
||||
GettingLine () const
|
||||
{
|
||||
return m_getting_line;
|
||||
}
|
||||
|
||||
void
|
||||
Hide ();
|
||||
|
||||
void
|
||||
Refresh();
|
||||
|
||||
void
|
||||
Interrupt ();
|
||||
|
||||
void
|
||||
SetAutoCompleteCallback (CompleteCallbackType callback,
|
||||
void *baton)
|
||||
{
|
||||
m_completion_callback = callback;
|
||||
m_completion_callback_baton = baton;
|
||||
}
|
||||
|
||||
void
|
||||
SetLineCompleteCallback (LineCompletedCallbackType callback,
|
||||
void *baton)
|
||||
{
|
||||
m_line_complete_callback = callback;
|
||||
m_line_complete_callback_baton = baton;
|
||||
}
|
||||
|
||||
size_t
|
||||
Push (const char *bytes, size_t len);
|
||||
|
||||
// Cache bytes and use them for input without using a FILE. Calling this function
|
||||
// will set the getc callback in the editline
|
||||
size_t
|
||||
SetInputBuffer (const char *c, size_t len);
|
||||
|
||||
static int
|
||||
GetCharFromInputFileCallback (::EditLine *e, char *c);
|
||||
|
||||
void
|
||||
SetGetCharCallback (GetCharCallbackType callback);
|
||||
|
||||
const char *
|
||||
GetPrompt();
|
||||
|
||||
void
|
||||
SetPrompt (const char *p);
|
||||
|
||||
private:
|
||||
|
||||
Error
|
||||
PrivateGetLine(std::string &line);
|
||||
|
||||
FileSpec
|
||||
GetHistoryFile();
|
||||
|
||||
unsigned char
|
||||
HandleCompletion (int ch);
|
||||
|
||||
int
|
||||
GetChar (char *c);
|
||||
|
||||
|
||||
static unsigned char
|
||||
CallbackEditPrevLine (::EditLine *e, int ch);
|
||||
|
||||
static unsigned char
|
||||
CallbackEditNextLine (::EditLine *e, int ch);
|
||||
|
||||
static unsigned char
|
||||
CallbackComplete (::EditLine *e, int ch);
|
||||
|
||||
static const char *
|
||||
GetPromptCallback (::EditLine *e);
|
||||
|
||||
static Editline *
|
||||
GetClientData (::EditLine *e);
|
||||
|
||||
static FILE *
|
||||
GetFilePointer (::EditLine *e, int fd);
|
||||
|
||||
static int
|
||||
GetCharInputBufferCallback (::EditLine *e, char *c);
|
||||
|
||||
enum class Command
|
||||
{
|
||||
None = 0,
|
||||
EditPrevLine,
|
||||
EditNextLine,
|
||||
};
|
||||
::EditLine *m_editline;
|
||||
::History *m_history;
|
||||
::HistEvent m_history_event;
|
||||
std::string m_program;
|
||||
std::string m_prompt;
|
||||
std::string m_lines_prompt;
|
||||
std::string m_getc_buffer;
|
||||
Mutex m_getc_mutex;
|
||||
Condition m_getc_cond;
|
||||
CompleteCallbackType m_completion_callback;
|
||||
void *m_completion_callback_baton;
|
||||
// Mutex m_gets_mutex; // Make sure only one thread
|
||||
LineCompletedCallbackType m_line_complete_callback;
|
||||
void *m_line_complete_callback_baton;
|
||||
Command m_lines_command;
|
||||
uint32_t m_lines_curr_line;
|
||||
uint32_t m_lines_max_line;
|
||||
bool m_prompt_with_line_numbers;
|
||||
bool m_getting_line;
|
||||
bool m_got_eof; // Set to true when we detect EOF
|
||||
bool m_interrupted;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Editline);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #if defined(__cplusplus)
|
||||
#endif // liblldb_Host_h_
|
@ -51,7 +51,10 @@ class File
|
||||
m_descriptor (kInvalidDescriptor),
|
||||
m_stream (kInvalidStream),
|
||||
m_options (0),
|
||||
m_owned (false)
|
||||
m_own_stream (false),
|
||||
m_own_descriptor (false),
|
||||
m_is_interactive (eLazyBoolCalculate),
|
||||
m_is_real_terminal (eLazyBoolCalculate)
|
||||
{
|
||||
}
|
||||
|
||||
@ -59,7 +62,10 @@ class File
|
||||
m_descriptor (kInvalidDescriptor),
|
||||
m_stream (fh),
|
||||
m_options (0),
|
||||
m_owned (transfer_ownership)
|
||||
m_own_stream (transfer_ownership),
|
||||
m_own_descriptor (false),
|
||||
m_is_interactive (eLazyBoolCalculate),
|
||||
m_is_real_terminal (eLazyBoolCalculate)
|
||||
{
|
||||
}
|
||||
|
||||
@ -111,13 +117,15 @@ class File
|
||||
uint32_t options,
|
||||
uint32_t permissions = lldb::eFilePermissionsFileDefault);
|
||||
|
||||
File (int fd, bool tranfer_ownership) :
|
||||
File (int fd, bool transfer_ownership) :
|
||||
m_descriptor (fd),
|
||||
m_stream (kInvalidStream),
|
||||
m_options (0),
|
||||
m_owned (tranfer_ownership)
|
||||
m_own_stream (false),
|
||||
m_own_descriptor (transfer_ownership)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
///
|
||||
@ -458,6 +466,32 @@ class File
|
||||
static uint32_t
|
||||
GetPermissions (const char *path, Error &error);
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return true if this file is interactive.
|
||||
///
|
||||
/// @return
|
||||
/// True if this file is a terminal (tty or pty), false
|
||||
/// otherwise.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
GetIsInteractive ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return true if this file from a real terminal.
|
||||
///
|
||||
/// Just knowing a file is a interactive isn't enough, we also need
|
||||
/// to know if the terminal has a width and height so we can do
|
||||
/// cursor movement and other terminal maninpulations by sending
|
||||
/// escape sequences.
|
||||
///
|
||||
/// @return
|
||||
/// True if this file is a terminal (tty, not a pty) that has
|
||||
/// a non-zero width and height, false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
GetIsRealTerminal ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Output printf formatted output to the stream.
|
||||
///
|
||||
@ -476,6 +510,12 @@ class File
|
||||
size_t
|
||||
PrintfVarArg(const char *format, va_list args);
|
||||
|
||||
|
||||
void
|
||||
SetOptions (uint32_t options)
|
||||
{
|
||||
m_options = options;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
@ -491,13 +531,19 @@ class File
|
||||
return m_stream != kInvalidStream;
|
||||
}
|
||||
|
||||
void
|
||||
CalculateInteractiveAndTerminal ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
//------------------------------------------------------------------
|
||||
int m_descriptor;
|
||||
FILE *m_stream;
|
||||
uint32_t m_options;
|
||||
bool m_owned;
|
||||
bool m_own_stream;
|
||||
bool m_own_descriptor;
|
||||
LazyBool m_is_interactive;
|
||||
LazyBool m_is_real_terminal;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
@ -534,7 +534,7 @@ class FileSpec
|
||||
/// as many bytes as possible.
|
||||
///
|
||||
/// @return
|
||||
/// A shared pointer to the memeory mapped data. This shared
|
||||
/// A shared pointer to the memory mapped data. This shared
|
||||
/// pointer can contain a NULL DataBuffer pointer, so the contained
|
||||
/// pointer must be checked prior to using it.
|
||||
//------------------------------------------------------------------
|
||||
|
@ -201,6 +201,23 @@ class Host
|
||||
static const ConstString &
|
||||
GetTargetTriple ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Gets the name of the distribution (i.e. distributor id).
|
||||
///
|
||||
/// On Linux, this will return the equivalent of lsb_release -i.
|
||||
/// Android will return 'android'. Other systems may return
|
||||
/// nothing.
|
||||
///
|
||||
/// @return
|
||||
/// A ConstString reference containing the OS distribution id.
|
||||
/// The return string will be all lower case, with whitespace
|
||||
/// replaced with underscores. The return string will be
|
||||
/// empty (result.AsCString() will return NULL) if the distribution
|
||||
/// cannot be obtained.
|
||||
//------------------------------------------------------------------
|
||||
static const ConstString &
|
||||
GetDistributionId ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the process ID for the calling process.
|
||||
///
|
||||
@ -459,7 +476,15 @@ class Host
|
||||
|
||||
static bool
|
||||
GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
|
||||
|
||||
|
||||
#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__)
|
||||
static short
|
||||
GetPosixspawnFlags (ProcessLaunchInfo &launch_info);
|
||||
|
||||
static Error
|
||||
LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid);
|
||||
#endif
|
||||
|
||||
static lldb::pid_t
|
||||
LaunchApplication (const FileSpec &app_file_spec);
|
||||
|
||||
|
20
include/lldb/Host/HostGetOpt.h
Normal file
20
include/lldb/Host/HostGetOpt.h
Normal file
@ -0,0 +1,20 @@
|
||||
//===-- GetOpt.h ------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#pragma once
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <lldb/Host/windows/GetOptInc.h>
|
||||
|
||||
#endif
|
@ -18,7 +18,6 @@
|
||||
#include <winsock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
typedef ADDRESS_FAMILY sa_family_t;
|
||||
typedef USHORT in_port_t;
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
@ -103,7 +102,7 @@ class SocketAddress
|
||||
//------------------------------------------------------------------
|
||||
// Get the port if the socket address for the family has a port
|
||||
//------------------------------------------------------------------
|
||||
in_port_t
|
||||
uint16_t
|
||||
GetPort () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -111,7 +110,7 @@ class SocketAddress
|
||||
// The family must be set correctly prior to calling this function.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
SetPort (in_port_t port);
|
||||
SetPort (uint16_t port);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Set the socket address according to the first match from a call
|
||||
@ -121,10 +120,12 @@ class SocketAddress
|
||||
// address.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
SetAddress (const struct addrinfo *hints_ptr, // Optional hints where the family, protocol and other things can be specified.
|
||||
const char *host, // Hostname ("foo.bar.com" or "foo" or IP address string ("123.234.12.1" or "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
|
||||
const char *service, // Protocol name ("tcp", "http", etc) or a raw port number string ("81")
|
||||
struct addrinfo *addr_info_ptr); // If non-NULL, this will get filled in with the match
|
||||
getaddrinfo (const char *host, // Hostname ("foo.bar.com" or "foo" or IP address string ("123.234.12.1" or "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
|
||||
const char *service, // Protocol name ("tcp", "http", etc) or a raw port number string ("81")
|
||||
int ai_family = PF_UNSPEC,
|
||||
int ai_socktype = 0,
|
||||
int ai_protocol = 0,
|
||||
int ai_flags = 0);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Quick way to set the SocketAddress to localhost given the family.
|
||||
@ -133,7 +134,11 @@ class SocketAddress
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
SetToLocalhost (sa_family_t family,
|
||||
in_port_t port);
|
||||
uint16_t port);
|
||||
|
||||
bool
|
||||
SetToAnyAddress (sa_family_t family,
|
||||
uint16_t port);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Returns true if there is a valid socket address in this object.
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Interpreter/CommandHistory.h"
|
||||
#include "lldb/Interpreter/CommandObject.h"
|
||||
@ -29,7 +30,8 @@ namespace lldb_private {
|
||||
|
||||
class CommandInterpreter :
|
||||
public Broadcaster,
|
||||
public Properties
|
||||
public Properties,
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, OptionArgVectorSP> OptionArgMap;
|
||||
@ -213,10 +215,10 @@ class CommandInterpreter :
|
||||
void
|
||||
HandleCommandsFromFile (FileSpec &file,
|
||||
ExecutionContext *context,
|
||||
bool stop_on_continue,
|
||||
bool stop_on_error,
|
||||
bool echo_commands,
|
||||
bool print_results,
|
||||
LazyBool stop_on_continue,
|
||||
LazyBool stop_on_error,
|
||||
LazyBool echo_commands,
|
||||
LazyBool print_results,
|
||||
LazyBool add_to_history,
|
||||
CommandReturnObject &result);
|
||||
|
||||
@ -305,7 +307,8 @@ class CommandInterpreter :
|
||||
ExecutionContext
|
||||
GetExecutionContext()
|
||||
{
|
||||
return m_exe_ctx_ref.Lock();
|
||||
const bool thread_and_frame_only_if_stopped = true;
|
||||
return m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped);
|
||||
}
|
||||
|
||||
void
|
||||
@ -317,20 +320,12 @@ class CommandInterpreter :
|
||||
const char *
|
||||
ProcessEmbeddedScriptCommands (const char *arg);
|
||||
|
||||
const char *
|
||||
GetPrompt ();
|
||||
|
||||
void
|
||||
SetPrompt (const char *);
|
||||
UpdatePrompt (const char *);
|
||||
|
||||
bool Confirm (const char *message, bool default_answer);
|
||||
|
||||
static size_t
|
||||
GetConfirmationInputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction action,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
bool
|
||||
Confirm (const char *message,
|
||||
bool default_answer);
|
||||
|
||||
void
|
||||
LoadCommandDictionary ();
|
||||
@ -395,8 +390,12 @@ class CommandInterpreter :
|
||||
bool
|
||||
GetBatchCommandMode () { return m_batch_command_mode; }
|
||||
|
||||
void
|
||||
SetBatchCommandMode (bool value) { m_batch_command_mode = value; }
|
||||
bool
|
||||
SetBatchCommandMode (bool value) {
|
||||
const bool old_value = m_batch_command_mode;
|
||||
m_batch_command_mode = value;
|
||||
return old_value;
|
||||
}
|
||||
|
||||
void
|
||||
ChildrenTruncated ()
|
||||
@ -435,6 +434,25 @@ class CommandInterpreter :
|
||||
return m_command_history;
|
||||
}
|
||||
|
||||
bool
|
||||
IsActive ();
|
||||
|
||||
void
|
||||
RunCommandInterpreter (bool auto_handle_events,
|
||||
bool spawn_thread);
|
||||
|
||||
void
|
||||
GetLLDBCommandsFromIOHandler (const char *prompt,
|
||||
IOHandlerDelegate &delegate,
|
||||
bool asynchronously,
|
||||
void *baton);
|
||||
|
||||
void
|
||||
GetPythonCommandsFromIOHandler (const char *prompt,
|
||||
IOHandlerDelegate &delegate,
|
||||
bool asynchronously,
|
||||
void *baton);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Properties
|
||||
//------------------------------------------------------------------
|
||||
@ -450,12 +468,31 @@ class CommandInterpreter :
|
||||
protected:
|
||||
friend class Debugger;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// IOHandlerDelegate functions
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler,
|
||||
std::string &line);
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
if (ch == 'd')
|
||||
return ConstString("quit\n");
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
size_t
|
||||
GetProcessOutput ();
|
||||
|
||||
void
|
||||
SetSynchronous (bool value);
|
||||
|
||||
lldb::CommandObjectSP
|
||||
GetCommandSP (const char *cmd, bool include_aliases = true, bool exact = true, StringList *matches = NULL);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Error
|
||||
@ -473,10 +510,12 @@ class CommandInterpreter :
|
||||
CommandHistory m_command_history;
|
||||
std::string m_repeat_command; // Stores the command that will be executed for an empty command string.
|
||||
std::unique_ptr<ScriptInterpreter> m_script_interpreter_ap;
|
||||
lldb::IOHandlerSP m_command_io_handler_sp;
|
||||
char m_comment_char;
|
||||
bool m_batch_command_mode;
|
||||
ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated children and whether the user has been told
|
||||
uint32_t m_command_source_depth;
|
||||
std::vector<uint32_t> m_command_source_flags;
|
||||
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace lldb_private {
|
||||
{
|
||||
}
|
||||
|
||||
PythonObject (PyObject* py_obj) :
|
||||
explicit PythonObject (PyObject* py_obj) :
|
||||
m_py_obj(NULL)
|
||||
{
|
||||
Reset (py_obj);
|
||||
@ -43,7 +43,7 @@ namespace lldb_private {
|
||||
Reset (rhs.m_py_obj);
|
||||
}
|
||||
|
||||
PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
explicit PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
|
||||
virtual
|
||||
~PythonObject ()
|
||||
@ -51,18 +51,10 @@ namespace lldb_private {
|
||||
Reset (NULL);
|
||||
}
|
||||
|
||||
const PythonObject &
|
||||
operator = (const PythonObject &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
Reset (rhs.m_py_obj);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
Reset (const PythonObject &object)
|
||||
{
|
||||
return Reset(object.GetPythonObject());
|
||||
return Reset(object.get());
|
||||
}
|
||||
|
||||
virtual bool
|
||||
@ -90,11 +82,11 @@ namespace lldb_private {
|
||||
Dump (Stream &strm) const;
|
||||
|
||||
PyObject*
|
||||
GetPythonObject () const
|
||||
get () const
|
||||
{
|
||||
return m_py_obj;
|
||||
}
|
||||
|
||||
|
||||
PythonString
|
||||
Repr ();
|
||||
|
||||
@ -159,7 +151,7 @@ namespace lldb_private {
|
||||
{
|
||||
public:
|
||||
|
||||
PythonList ();
|
||||
PythonList (bool create_empty);
|
||||
PythonList (PyObject* py_obj);
|
||||
PythonList (const PythonObject &object);
|
||||
PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
@ -186,7 +178,7 @@ namespace lldb_private {
|
||||
{
|
||||
public:
|
||||
|
||||
PythonDictionary ();
|
||||
explicit PythonDictionary (bool create_empty);
|
||||
PythonDictionary (PyObject* object);
|
||||
PythonDictionary (const PythonObject &object);
|
||||
PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
@ -220,6 +212,9 @@ namespace lldb_private {
|
||||
PythonObject
|
||||
GetValueAtPosition (uint32_t pos) const;
|
||||
|
||||
void
|
||||
SetItemForKey (const PythonString &key, PyObject *value);
|
||||
|
||||
void
|
||||
SetItemForKey (const PythonString &key, const PythonObject& value);
|
||||
};
|
||||
|
@ -245,11 +245,13 @@ class ScriptInterpreter
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
ExecuteMultipleLines (const char *in_string,
|
||||
const ExecuteScriptOptions &options = ExecuteScriptOptions())
|
||||
{
|
||||
return true;
|
||||
Error error;
|
||||
error.SetErrorString("not implemented");
|
||||
return error;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
|
@ -19,16 +19,21 @@
|
||||
|
||||
#include "lldb/lldb-python.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreter.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Interpreter/PythonDataObjects.h"
|
||||
#include "lldb/Host/Terminal.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ScriptInterpreterPython : public ScriptInterpreter
|
||||
class ScriptInterpreterPython :
|
||||
public ScriptInterpreter,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
public:
|
||||
|
||||
friend class IOHandlerPythonInterpreter;
|
||||
|
||||
ScriptInterpreterPython (CommandInterpreter &interpreter);
|
||||
|
||||
~ScriptInterpreterPython ();
|
||||
@ -47,7 +52,7 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
void *ret_value,
|
||||
const ExecuteScriptOptions &options = ExecuteScriptOptions());
|
||||
|
||||
bool
|
||||
lldb_private::Error
|
||||
ExecuteMultipleLines (const char *in_string,
|
||||
const ExecuteScriptOptions &options = ExecuteScriptOptions());
|
||||
|
||||
@ -134,20 +139,20 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
bool
|
||||
GenerateWatchpointCommandCallbackData (StringList &input, std::string& output);
|
||||
|
||||
static size_t
|
||||
GenerateBreakpointOptionsCommandCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
static size_t
|
||||
GenerateWatchpointOptionsCommandCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
// static size_t
|
||||
// GenerateBreakpointOptionsCommandCallback (void *baton,
|
||||
// InputReader &reader,
|
||||
// lldb::InputReaderAction notification,
|
||||
// const char *bytes,
|
||||
// size_t bytes_len);
|
||||
//
|
||||
// static size_t
|
||||
// GenerateWatchpointOptionsCommandCallback (void *baton,
|
||||
// InputReader &reader,
|
||||
// lldb::InputReaderAction notification,
|
||||
// const char *bytes,
|
||||
// size_t bytes_len);
|
||||
|
||||
static bool
|
||||
BreakpointCallbackFunction (void *baton,
|
||||
StoppointCallbackContext *context,
|
||||
@ -238,9 +243,6 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
virtual void
|
||||
ResetOutputFileHandle (FILE *new_fh);
|
||||
|
||||
static lldb::thread_result_t
|
||||
RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton);
|
||||
|
||||
static void
|
||||
InitializePrivate ();
|
||||
|
||||
@ -266,10 +268,29 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
|
||||
SWIGPython_GetDynamicSetting swig_plugin_get);
|
||||
|
||||
const char *
|
||||
GetDictionaryName ()
|
||||
{
|
||||
return m_dictionary_name.c_str();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// IOHandlerDelegate
|
||||
//----------------------------------------------------------------------
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler);
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
|
||||
|
||||
protected:
|
||||
|
||||
bool
|
||||
EnterSession (bool init_lldb_globals);
|
||||
EnterSession (uint16_t on_entry_flags,
|
||||
FILE *in,
|
||||
FILE *out,
|
||||
FILE *err);
|
||||
|
||||
void
|
||||
LeaveSession ();
|
||||
@ -279,8 +300,6 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
|
||||
void
|
||||
RestoreTerminalState ();
|
||||
|
||||
private:
|
||||
|
||||
class SynchronicityHandler
|
||||
{
|
||||
@ -322,7 +341,7 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject);
|
||||
};
|
||||
|
||||
public:
|
||||
class Locker : public ScriptInterpreterLocker
|
||||
{
|
||||
public:
|
||||
@ -331,7 +350,8 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
{
|
||||
AcquireLock = 0x0001,
|
||||
InitSession = 0x0002,
|
||||
InitGlobals = 0x0004
|
||||
InitGlobals = 0x0004,
|
||||
NoSTDIN = 0x0008
|
||||
};
|
||||
|
||||
enum OnLeave
|
||||
@ -344,7 +364,9 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
Locker (ScriptInterpreterPython *py_interpreter = NULL,
|
||||
uint16_t on_entry = AcquireLock | InitSession,
|
||||
uint16_t on_leave = FreeLock | TearDownSession,
|
||||
FILE* wait_msg_handle = NULL);
|
||||
FILE *in = NULL,
|
||||
FILE *out = NULL,
|
||||
FILE *err = NULL);
|
||||
|
||||
~Locker ();
|
||||
|
||||
@ -354,7 +376,7 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
DoAcquireLock ();
|
||||
|
||||
bool
|
||||
DoInitSession (bool init_lldb_globals);
|
||||
DoInitSession (uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
|
||||
|
||||
bool
|
||||
DoFreeLock ();
|
||||
@ -367,59 +389,40 @@ class ScriptInterpreterPython : public ScriptInterpreter
|
||||
|
||||
bool m_teardown_session;
|
||||
ScriptInterpreterPython *m_python_interpreter;
|
||||
FILE* m_tmp_fh;
|
||||
// FILE* m_tmp_fh;
|
||||
PyGILState_STATE m_GILState;
|
||||
};
|
||||
|
||||
class PythonInputReaderManager
|
||||
{
|
||||
public:
|
||||
PythonInputReaderManager (ScriptInterpreterPython *interpreter);
|
||||
|
||||
explicit operator bool()
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
~PythonInputReaderManager();
|
||||
|
||||
private:
|
||||
|
||||
static size_t
|
||||
InputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
static lldb::thread_result_t
|
||||
RunPythonInputReader (lldb::thread_arg_t baton);
|
||||
|
||||
ScriptInterpreterPython *m_interpreter;
|
||||
lldb::DebuggerSP m_debugger_sp;
|
||||
lldb::InputReaderSP m_reader_sp;
|
||||
bool m_error;
|
||||
private:
|
||||
|
||||
enum ActiveIOHandler {
|
||||
eIOHandlerNone,
|
||||
eIOHandlerBreakpoint,
|
||||
eIOHandlerWatchpoint
|
||||
};
|
||||
PythonObject &
|
||||
GetMainModule ();
|
||||
|
||||
PythonDictionary &
|
||||
GetSessionDictionary ();
|
||||
|
||||
PythonDictionary &
|
||||
GetSysModuleDictionary ();
|
||||
|
||||
static size_t
|
||||
InputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
|
||||
lldb_utility::PseudoTerminal m_embedded_thread_pty;
|
||||
lldb_utility::PseudoTerminal m_embedded_python_pty;
|
||||
lldb::InputReaderSP m_embedded_thread_input_reader_sp;
|
||||
lldb::InputReaderSP m_embedded_python_input_reader_sp;
|
||||
FILE *m_dbg_stdout;
|
||||
PyObject *m_new_sysout;
|
||||
PyObject *m_old_sysout;
|
||||
PyObject *m_old_syserr;
|
||||
PyObject *m_run_one_line;
|
||||
bool
|
||||
GetEmbeddedInterpreterModuleObjects ();
|
||||
|
||||
PythonObject m_saved_stdin;
|
||||
PythonObject m_saved_stdout;
|
||||
PythonObject m_saved_stderr;
|
||||
PythonObject m_main_module;
|
||||
PythonObject m_lldb_module;
|
||||
PythonDictionary m_session_dict;
|
||||
PythonDictionary m_sys_module_dict;
|
||||
PythonObject m_run_one_line_function;
|
||||
PythonObject m_run_one_line_str_global;
|
||||
std::string m_dictionary_name;
|
||||
TerminalState m_terminal_state;
|
||||
ActiveIOHandler m_active_io_handler;
|
||||
bool m_session_is_active;
|
||||
bool m_pty_slave_is_open;
|
||||
bool m_valid_session;
|
||||
|
@ -31,7 +31,7 @@ class FuncUnwinders
|
||||
// instructions are finished for migrating breakpoints past the
|
||||
// stack frame setup instructions when we don't have line table information.
|
||||
|
||||
FuncUnwinders (lldb_private::UnwindTable& unwind_table, lldb_private::UnwindAssembly *assembly_profiler, AddressRange range);
|
||||
FuncUnwinders (lldb_private::UnwindTable& unwind_table, const lldb::UnwindAssemblySP& assembly_profiler, AddressRange range);
|
||||
|
||||
~FuncUnwinders ();
|
||||
|
||||
@ -77,7 +77,7 @@ class FuncUnwinders
|
||||
|
||||
private:
|
||||
UnwindTable& m_unwind_table;
|
||||
UnwindAssembly *m_assembly_profiler;
|
||||
lldb::UnwindAssemblySP m_assembly_profiler;
|
||||
AddressRange m_range;
|
||||
|
||||
Mutex m_mutex;
|
||||
|
@ -608,6 +608,17 @@ class Function :
|
||||
size_t
|
||||
MemorySize () const;
|
||||
|
||||
lldb::DisassemblerSP
|
||||
GetInstructions (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache);
|
||||
|
||||
bool
|
||||
GetDisassembly (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache,
|
||||
Stream &strm);
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
|
@ -450,6 +450,21 @@ friend class lldb_private::Module;
|
||||
return FileSpecList();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Sets the load address for an entire module, assuming a rigid
|
||||
/// slide of sections, if possible in the implementation.
|
||||
///
|
||||
/// @return
|
||||
/// Returns true iff any section's load address changed.
|
||||
//------------------------------------------------------------------
|
||||
virtual bool
|
||||
SetLoadAddress(Target &target,
|
||||
lldb::addr_t value,
|
||||
bool value_is_offset)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Gets whether endian swapping should occur when extracting data
|
||||
/// from this object file.
|
||||
|
@ -291,6 +291,17 @@ class Symbol :
|
||||
virtual void
|
||||
DumpSymbolContext (Stream *s);
|
||||
|
||||
lldb::DisassemblerSP
|
||||
GetInstructions (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache);
|
||||
|
||||
bool
|
||||
GetDisassembly (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache,
|
||||
Stream &strm);
|
||||
|
||||
protected:
|
||||
|
||||
uint32_t m_uid; // User ID (usually the original symbol table index)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "lldb/Core/Address.h"
|
||||
#include "lldb/Core/Mangled.h"
|
||||
#include "lldb/Symbol/LineEntry.h"
|
||||
#include "lldb/Utility/Iterable.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
@ -552,6 +553,14 @@ class SymbolContextList
|
||||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
collection m_symbol_contexts; ///< The list of symbol contexts.
|
||||
|
||||
public:
|
||||
typedef AdaptedIterable<collection, SymbolContext, vector_adapter> SymbolContextIterable;
|
||||
SymbolContextIterable
|
||||
SymbolContexts()
|
||||
{
|
||||
return SymbolContextIterable(m_symbol_contexts);
|
||||
}
|
||||
};
|
||||
|
||||
bool operator== (const SymbolContext& lhs, const SymbolContext& rhs);
|
||||
|
@ -417,7 +417,15 @@ class TypePair {
|
||||
return type_sp->GetClangLayoutType().GetLValueReferenceType();
|
||||
return clang_type.GetLValueReferenceType();
|
||||
}
|
||||
|
||||
|
||||
ClangASTType
|
||||
GetTypedefedType () const
|
||||
{
|
||||
if (type_sp)
|
||||
return type_sp->GetClangFullType().GetTypedefedType();
|
||||
return clang_type.GetTypedefedType();
|
||||
}
|
||||
|
||||
ClangASTType
|
||||
GetDereferencedType () const
|
||||
{
|
||||
@ -512,6 +520,9 @@ class TypeImpl
|
||||
TypeImpl
|
||||
GetReferenceType () const;
|
||||
|
||||
TypeImpl
|
||||
GetTypedefedType () const;
|
||||
|
||||
TypeImpl
|
||||
GetDereferencedType () const;
|
||||
|
||||
|
@ -57,7 +57,7 @@ class UnwindTable
|
||||
|
||||
bool m_initialized; // delay some initialization until ObjectFile is set up
|
||||
|
||||
UnwindAssembly* m_assembly_profiler;
|
||||
lldb::UnwindAssemblySP m_assembly_profiler;
|
||||
|
||||
DWARFCallFrameInfo* m_eh_frame;
|
||||
|
||||
|
@ -245,6 +245,60 @@ class DynamicLoader :
|
||||
}
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Utility methods for derived classes
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/// Checks to see if the target module has changed, updates the target
|
||||
/// accordingly and returns the target executable module.
|
||||
lldb::ModuleSP
|
||||
GetTargetExecutable();
|
||||
|
||||
/// Updates the load address of every allocatable section in @p module.
|
||||
///
|
||||
/// @param module The module to traverse.
|
||||
///
|
||||
/// @param link_map_addr The virtual address of the link map for the @p module.
|
||||
///
|
||||
/// @param base_addr The virtual base address @p module is loaded at.
|
||||
virtual void
|
||||
UpdateLoadedSections(lldb::ModuleSP module,
|
||||
lldb::addr_t link_map_addr,
|
||||
lldb::addr_t base_addr);
|
||||
|
||||
// Utility method so base classes can share implementation of UpdateLoadedSections
|
||||
void
|
||||
UpdateLoadedSectionsCommon(lldb::ModuleSP module,
|
||||
lldb::addr_t base_addr);
|
||||
|
||||
/// Removes the loaded sections from the target in @p module.
|
||||
///
|
||||
/// @param module The module to traverse.
|
||||
virtual void
|
||||
UnloadSections(const lldb::ModuleSP module);
|
||||
|
||||
// Utility method so base classes can share implementation of UnloadSections
|
||||
void
|
||||
UnloadSectionsCommon(const lldb::ModuleSP module);
|
||||
|
||||
/// Locates or creates a module given by @p file and updates/loads the
|
||||
/// resulting module at the virtual base address @p base_addr.
|
||||
lldb::ModuleSP
|
||||
LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr);
|
||||
|
||||
const lldb_private::SectionList *
|
||||
GetSectionListFromModule(const lldb::ModuleSP module) const;
|
||||
|
||||
// Read an unsigned int of the given size from memory at the given addr.
|
||||
// Return -1 if the read fails, otherwise return the result as an int64_t.
|
||||
int64_t
|
||||
ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes);
|
||||
|
||||
// Read a pointer from memory at the given addr.
|
||||
// Return LLDB_INVALID_ADDRESS if the read fails.
|
||||
lldb::addr_t
|
||||
ReadPointer(lldb::addr_t addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
|
@ -298,7 +298,7 @@ class ExecutionContextRef
|
||||
/// any valid weak references in this object.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext
|
||||
Lock () const;
|
||||
Lock (bool thread_and_frame_only_if_stopped) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true if this object has a weak reference to a thread.
|
||||
@ -402,7 +402,7 @@ class ExecutionContext
|
||||
ExecutionContext (const lldb::ThreadWP &thread_wp);
|
||||
ExecutionContext (const lldb::StackFrameWP &frame_wp);
|
||||
ExecutionContext (const ExecutionContextRef &exe_ctx_ref);
|
||||
ExecutionContext (const ExecutionContextRef *exe_ctx_ref);
|
||||
ExecutionContext (const ExecutionContextRef *exe_ctx_ref, bool thread_and_frame_only_if_stopped = false);
|
||||
|
||||
// These two variants take in a locker, and grab the target, lock the API mutex into locker, then
|
||||
// fill in the rest of the shared pointers.
|
||||
|
@ -314,9 +314,9 @@ namespace lldb_private {
|
||||
/// An error object.
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
GetFile (const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file);
|
||||
GetFileWithUUID (const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Locate the scripting resource given a module specification.
|
||||
@ -835,6 +835,29 @@ namespace lldb_private {
|
||||
return LLDB_INVALID_QUEUE_ID;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Provide a list of trap handler function names for this platform
|
||||
///
|
||||
/// The unwinder needs to treat trap handlers specially -- the stack
|
||||
/// frame may not be aligned correctly for a trap handler (the kernel
|
||||
/// often won't perturb the stack pointer, or won't re-align it properly,
|
||||
/// in the process of calling the handler) and the frame above the handler
|
||||
/// needs to be treated by the unwinder's "frame 0" rules instead of its
|
||||
/// "middle of the stack frame" rules.
|
||||
///
|
||||
/// In a user process debugging scenario, the list of trap handlers is
|
||||
/// typically just "_sigtramp".
|
||||
///
|
||||
/// The Platform base class provides the m_trap_handlers ivar but it does
|
||||
/// not populate it. Subclasses should add the names of the asynchronous
|
||||
/// signal handler routines as needed. For most Unix platforms, add _sigtramp.
|
||||
///
|
||||
/// @return
|
||||
/// A list of symbol names. The list may be empty.
|
||||
//------------------------------------------------------------------
|
||||
virtual const std::vector<ConstString> &
|
||||
GetTrapHandlerSymbolNames ();
|
||||
|
||||
protected:
|
||||
bool m_is_host;
|
||||
// Set to true when we are able to actually set the OS version while
|
||||
@ -867,6 +890,24 @@ namespace lldb_private {
|
||||
std::string m_ssh_opts;
|
||||
bool m_ignores_remote_hostname;
|
||||
std::string m_local_cache_directory;
|
||||
std::vector<ConstString> m_trap_handlers;
|
||||
bool m_calculated_trap_handlers;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Ask the Platform subclass to fill in the list of trap handler names
|
||||
///
|
||||
/// For most Unix user process environments, this will be a single
|
||||
/// function name, _sigtramp. More specialized environments may have
|
||||
/// additional handler names. The unwinder code needs to know when a
|
||||
/// trap handler is on the stack because the unwind rules for the frame
|
||||
/// that caused the trap are different.
|
||||
///
|
||||
/// The base class Platform ivar m_trap_handlers should be updated by
|
||||
/// the Platform subclass when this method is called. If there are no
|
||||
/// predefined trap handlers, this method may be a no-op.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
CalculateTrapHandlerSymbolNames () = 0;
|
||||
|
||||
const char *
|
||||
GetCachedUserName (uint32_t uid)
|
||||
@ -1115,7 +1156,9 @@ namespace lldb_private {
|
||||
|
||||
bool m_ssh;
|
||||
std::string m_ssh_opts;
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformSSH);
|
||||
};
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
#include "lldb/Target/Memory.h"
|
||||
#include "lldb/Target/QueueList.h"
|
||||
#include "lldb/Target/ThreadList.h"
|
||||
#include "lldb/Target/UnixSignals.h"
|
||||
#include "lldb/Utility/PseudoTerminal.h"
|
||||
@ -534,7 +535,8 @@ class ProcessLaunchInfo : public ProcessInfo
|
||||
m_resume_count (0),
|
||||
m_monitor_callback (NULL),
|
||||
m_monitor_callback_baton (NULL),
|
||||
m_monitor_signals (false)
|
||||
m_monitor_signals (false),
|
||||
m_hijack_listener_sp ()
|
||||
{
|
||||
}
|
||||
|
||||
@ -553,7 +555,8 @@ class ProcessLaunchInfo : public ProcessInfo
|
||||
m_resume_count (0),
|
||||
m_monitor_callback (NULL),
|
||||
m_monitor_callback_baton (NULL),
|
||||
m_monitor_signals (false)
|
||||
m_monitor_signals (false),
|
||||
m_hijack_listener_sp ()
|
||||
{
|
||||
if (stdin_path)
|
||||
{
|
||||
@ -780,6 +783,7 @@ class ProcessLaunchInfo : public ProcessInfo
|
||||
m_flags.Clear();
|
||||
m_file_actions.clear();
|
||||
m_resume_count = 0;
|
||||
m_hijack_listener_sp.reset();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -799,6 +803,18 @@ class ProcessLaunchInfo : public ProcessInfo
|
||||
m_monitor_signals = monitor_signals;
|
||||
}
|
||||
|
||||
Host::MonitorChildProcessCallback
|
||||
GetMonitorProcessCallback ()
|
||||
{
|
||||
return m_monitor_callback;
|
||||
}
|
||||
|
||||
const void*
|
||||
GetMonitorProcessBaton () const
|
||||
{
|
||||
return m_monitor_callback_baton;
|
||||
}
|
||||
|
||||
bool
|
||||
MonitorProcess () const
|
||||
{
|
||||
@ -818,6 +834,19 @@ class ProcessLaunchInfo : public ProcessInfo
|
||||
{
|
||||
return m_pty;
|
||||
}
|
||||
|
||||
lldb::ListenerSP
|
||||
GetHijackListener () const
|
||||
{
|
||||
return m_hijack_listener_sp;
|
||||
}
|
||||
|
||||
void
|
||||
SetHijackListener (const lldb::ListenerSP &listener_sp)
|
||||
{
|
||||
m_hijack_listener_sp = listener_sp;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
std::string m_working_dir;
|
||||
@ -830,7 +859,7 @@ class ProcessLaunchInfo : public ProcessInfo
|
||||
Host::MonitorChildProcessCallback m_monitor_callback;
|
||||
void *m_monitor_callback_baton;
|
||||
bool m_monitor_signals;
|
||||
|
||||
lldb::ListenerSP m_hijack_listener_sp;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -863,6 +892,7 @@ class ProcessAttachInfo : public ProcessInstanceInfo
|
||||
ProcessInfo::operator= (launch_info);
|
||||
SetProcessPluginName (launch_info.GetProcessPluginName());
|
||||
SetResumeCount (launch_info.GetResumeCount());
|
||||
SetHijackListener(launch_info.GetHijackListener());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -952,7 +982,22 @@ class ProcessAttachInfo : public ProcessInstanceInfo
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
lldb::ListenerSP
|
||||
GetHijackListener () const
|
||||
{
|
||||
return m_hijack_listener_sp;
|
||||
}
|
||||
|
||||
void
|
||||
SetHijackListener (const lldb::ListenerSP &listener_sp)
|
||||
{
|
||||
m_hijack_listener_sp = listener_sp;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
lldb::ListenerSP m_hijack_listener_sp;
|
||||
std::string m_plugin_name;
|
||||
uint32_t m_resume_count; // How many times do we resume after launching
|
||||
bool m_wait_for_launch;
|
||||
@ -1366,10 +1411,11 @@ class Process :
|
||||
public ExecutionContextScope,
|
||||
public PluginInterface
|
||||
{
|
||||
friend class ThreadList;
|
||||
friend class ClangFunction; // For WaitForStateChangeEventsPrivate
|
||||
friend class ProcessEventData;
|
||||
friend class StopInfo;
|
||||
friend class ClangFunction; // For WaitForStateChangeEventsPrivate
|
||||
friend class ProcessEventData;
|
||||
friend class StopInfo;
|
||||
friend class Target;
|
||||
friend class ThreadList;
|
||||
|
||||
public:
|
||||
|
||||
@ -2112,21 +2158,15 @@ friend class StopInfo;
|
||||
/// @param[in] process_name
|
||||
/// The name of the process to attach to.
|
||||
///
|
||||
/// @param[in] wait_for_launch
|
||||
/// If \b true, wait for the process to be launched and attach
|
||||
/// as soon as possible after it does launch. If \b false, then
|
||||
/// search for a matching process the currently exists.
|
||||
///
|
||||
/// @param[in] attach_info
|
||||
/// Information on how to do the attach. For example, GetUserID()
|
||||
/// will return the uid to attach as.
|
||||
///
|
||||
/// @return
|
||||
/// Returns \a pid if attaching was successful, or
|
||||
/// LLDB_INVALID_PROCESS_ID if attaching fails.
|
||||
/// Returns an error object.
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info)
|
||||
DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
|
||||
{
|
||||
Error error;
|
||||
error.SetErrorString("attach by name is not supported");
|
||||
@ -2225,7 +2265,7 @@ friend class StopInfo;
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
DoLaunch (Module *exe_module,
|
||||
const ProcessLaunchInfo &launch_info)
|
||||
ProcessLaunchInfo &launch_info)
|
||||
{
|
||||
Error error;
|
||||
error.SetErrorStringWithFormat("error: %s does not support launching processes", GetPluginName().GetCString());
|
||||
@ -2991,15 +3031,11 @@ friend class StopInfo;
|
||||
//------------------------------------------------------------------
|
||||
|
||||
virtual lldb::addr_t
|
||||
ResolveIndirectFunction(const Address *address, Error &error)
|
||||
{
|
||||
error.SetErrorStringWithFormat("error: %s does not support indirect functions in the debug process", GetPluginName().GetCString());
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
ResolveIndirectFunction(const Address *address, Error &error);
|
||||
|
||||
virtual Error
|
||||
GetMemoryRegionInfo (lldb::addr_t load_addr,
|
||||
MemoryRegionInfo &range_info)
|
||||
GetMemoryRegionInfo (lldb::addr_t load_addr,
|
||||
MemoryRegionInfo &range_info)
|
||||
{
|
||||
Error error;
|
||||
error.SetErrorString ("Process::GetMemoryRegionInfo() not supported");
|
||||
@ -3317,10 +3353,10 @@ friend class StopInfo;
|
||||
{
|
||||
return m_thread_list.Threads();
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
GetNextThreadIndexID (uint64_t thread_id);
|
||||
|
||||
|
||||
lldb::ThreadSP
|
||||
CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context);
|
||||
|
||||
@ -3333,6 +3369,27 @@ friend class StopInfo;
|
||||
uint32_t
|
||||
AssignIndexIDToThread(uint64_t thread_id);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Queue Queries
|
||||
//------------------------------------------------------------------
|
||||
|
||||
void
|
||||
UpdateQueueListIfNeeded ();
|
||||
|
||||
QueueList &
|
||||
GetQueueList ()
|
||||
{
|
||||
UpdateQueueListIfNeeded();
|
||||
return m_queue_list;
|
||||
}
|
||||
|
||||
QueueList::QueueIterable
|
||||
Queues ()
|
||||
{
|
||||
UpdateQueueListIfNeeded();
|
||||
return m_queue_list.Queues();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Event Handling
|
||||
//------------------------------------------------------------------
|
||||
@ -3343,10 +3400,15 @@ friend class StopInfo;
|
||||
// is set to the event which triggered the stop. If wait_always = false,
|
||||
// and the process is already stopped, this function returns immediately.
|
||||
lldb::StateType
|
||||
WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr = NULL, bool wait_always = true);
|
||||
WaitForProcessToStop (const TimeValue *timeout,
|
||||
lldb::EventSP *event_sp_ptr = NULL,
|
||||
bool wait_always = true,
|
||||
Listener *hijack_listener = NULL);
|
||||
|
||||
lldb::StateType
|
||||
WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp);
|
||||
WaitForStateChangedEvents (const TimeValue *timeout,
|
||||
lldb::EventSP &event_sp,
|
||||
Listener *hijack_listener); // Pass NULL to use builtin listener
|
||||
|
||||
Event *
|
||||
PeekAtStateChangedEvents ();
|
||||
@ -3513,6 +3575,12 @@ friend class StopInfo;
|
||||
void
|
||||
SetSTDIOFileDescriptor (int file_descriptor);
|
||||
|
||||
void
|
||||
WatchForSTDIN (IOHandler &io_handler);
|
||||
|
||||
void
|
||||
CancelWatchForSTDIN (bool exited);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Add a permanent region of memory that should never be read or
|
||||
// written to. This can be used to ensure that memory reads or writes
|
||||
@ -3645,6 +3713,12 @@ friend class StopInfo;
|
||||
{
|
||||
return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread);
|
||||
}
|
||||
|
||||
void
|
||||
ForceNextEventDelivery()
|
||||
{
|
||||
m_force_next_event_delivery = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Type definitions
|
||||
@ -3685,6 +3759,8 @@ friend class StopInfo;
|
||||
///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads
|
||||
ThreadList m_extended_thread_list; ///< Owner for extended threads that may be generated, cleared on natural stops
|
||||
uint32_t m_extended_thread_stop_id; ///< The natural stop id when extended_thread_list was last updated
|
||||
QueueList m_queue_list; ///< The list of libdispatch queues at a given stop point
|
||||
uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was last fetched
|
||||
std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver.
|
||||
std::vector<lldb::addr_t> m_image_tokens;
|
||||
Listener &m_listener;
|
||||
@ -3695,7 +3771,7 @@ friend class StopInfo;
|
||||
std::unique_ptr<SystemRuntime> m_system_runtime_ap;
|
||||
UnixSignals m_unix_signals; /// This is the current signal set for this process.
|
||||
lldb::ABISP m_abi_sp;
|
||||
lldb::InputReaderSP m_process_input_reader;
|
||||
lldb::IOHandlerSP m_process_input_reader;
|
||||
Communication m_stdio_communication;
|
||||
Mutex m_stdio_communication_mutex;
|
||||
std::string m_stdout_data;
|
||||
@ -3715,7 +3791,9 @@ friend class StopInfo;
|
||||
bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check.
|
||||
bool m_finalize_called;
|
||||
bool m_clear_thread_plans_on_stop;
|
||||
bool m_force_next_event_delivery;
|
||||
lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent.
|
||||
std::map<lldb::addr_t,lldb::addr_t> m_resolved_indirect_addresses;
|
||||
bool m_destroy_in_process;
|
||||
|
||||
enum {
|
||||
@ -3790,21 +3868,14 @@ friend class StopInfo;
|
||||
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
||||
|
||||
void
|
||||
PushProcessInputReader ();
|
||||
PushProcessIOHandler ();
|
||||
|
||||
void
|
||||
PopProcessInputReader ();
|
||||
PopProcessIOHandler ();
|
||||
|
||||
void
|
||||
ResetProcessInputReader ();
|
||||
|
||||
static size_t
|
||||
ProcessInputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
ResetProcessIOHandler ();
|
||||
|
||||
Error
|
||||
HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp);
|
||||
|
||||
|
189
include/lldb/Target/Queue.h
Normal file
189
include/lldb/Target/Queue.h
Normal file
@ -0,0 +1,189 @@
|
||||
//===-- Queue.h ------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_Queue_h_
|
||||
#define liblldb_Queue_h_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "lldb/lldb-forward.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/QueueItem.h"
|
||||
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Queue:
|
||||
// This class represents a libdispatch aka Grand Central Dispatch
|
||||
// queue in the process.
|
||||
//
|
||||
// A program using libdispatch will create queues, put work items
|
||||
// (functions, blocks) on the queues. The system will create /
|
||||
// reassign pthreads to execute the work items for the queues. A
|
||||
// serial queue will be associated with a single thread (or possibly
|
||||
// no thread, if it is not doing any work). A concurrent queue may
|
||||
// be associated with multiple threads.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
||||
class Queue :
|
||||
public std::enable_shared_from_this<Queue>
|
||||
{
|
||||
public:
|
||||
|
||||
Queue (lldb::ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue_name);
|
||||
|
||||
~Queue ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the QueueID for this Queue
|
||||
///
|
||||
/// A 64-bit ID number that uniquely identifies a queue at this particular
|
||||
/// stop_id. Currently the libdispatch serialnum is used for the QueueID;
|
||||
/// it is a number that starts at 1 for each process and increments with
|
||||
/// each queue. A serialnum is not reused for a different queue in the
|
||||
/// lifetime of that process execution.
|
||||
///
|
||||
/// @return
|
||||
/// The QueueID for this Queue.
|
||||
//------------------------------------------------------------------
|
||||
lldb::queue_id_t
|
||||
GetID ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the name of this Queue
|
||||
///
|
||||
/// @return
|
||||
/// The name of the queue, if one is available.
|
||||
/// A NULL pointer is returned if none is available.
|
||||
//------------------------------------------------------------------
|
||||
const char *
|
||||
GetName ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the IndexID for this Queue
|
||||
///
|
||||
/// This is currently the same as GetID(). If it changes in the future,
|
||||
/// it will be a small integer value (starting with 1) assigned to
|
||||
/// each queue that is seen during a Process lifetime.
|
||||
///
|
||||
/// Both the GetID and GetIndexID are being retained for Queues to
|
||||
/// maintain similar API to the Thread class, and allow for the
|
||||
/// possibility of GetID changing to a different source in the future.
|
||||
///
|
||||
/// @return
|
||||
/// The IndexID for this queue.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
GetIndexID ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the threads currently associated with this queue
|
||||
///
|
||||
/// Zero, one, or many threads may be executing code for a queue at
|
||||
/// a given point in time. This call returns the list of threads
|
||||
/// that are currently executing work for this queue.
|
||||
///
|
||||
/// @return
|
||||
/// The threads currently performing work for this queue
|
||||
//------------------------------------------------------------------
|
||||
std::vector<lldb::ThreadSP>
|
||||
GetThreads ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the items that are currently enqueued
|
||||
///
|
||||
/// "Enqueued" means that the item has been added to the queue to
|
||||
/// be done, but has not yet been done. When the item is going to
|
||||
/// be processed it is "dequeued".
|
||||
///
|
||||
/// @return
|
||||
/// The vector of enqueued items for this queue
|
||||
//------------------------------------------------------------------
|
||||
const std::vector<lldb::QueueItemSP> &
|
||||
GetPendingItems();
|
||||
|
||||
lldb::ProcessSP
|
||||
GetProcess() const
|
||||
{
|
||||
return m_process_wp.lock();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the number of work items that this queue is currently running
|
||||
///
|
||||
/// @return
|
||||
/// The number of work items currently executing. For a serial
|
||||
/// queue, this will be 0 or 1. For a concurrent queue, this
|
||||
/// may be any number.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
GetNumRunningWorkItems () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the number of work items enqueued on this queue
|
||||
///
|
||||
/// @return
|
||||
/// The number of work items currently enqueued, waiting to
|
||||
/// execute.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
GetNumPendingWorkItems () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the dispatch_queue_t structure address for this Queue
|
||||
///
|
||||
/// Get the address in the inferior process' memory of this Queue's
|
||||
/// dispatch_queue_t structure.
|
||||
///
|
||||
/// @return
|
||||
/// The address of the dispatch_queue_t structure, if known.
|
||||
/// LLDB_INVALID_ADDRESS will be returned if it is unavailable.
|
||||
//------------------------------------------------------------------
|
||||
lldb::addr_t
|
||||
GetLibdispatchQueueAddress () const;
|
||||
|
||||
|
||||
void
|
||||
SetNumRunningWorkItems (uint32_t count);
|
||||
|
||||
void
|
||||
SetNumPendingWorkItems (uint32_t count);
|
||||
|
||||
void
|
||||
SetLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t_addr);
|
||||
|
||||
void
|
||||
PushPendingQueueItem (lldb::QueueItemSP item)
|
||||
{
|
||||
m_pending_items.push_back (item);
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
// For Queue only
|
||||
//------------------------------------------------------------------
|
||||
|
||||
lldb::ProcessWP m_process_wp;
|
||||
lldb::queue_id_t m_queue_id;
|
||||
std::string m_queue_name;
|
||||
uint32_t m_running_work_items_count;
|
||||
uint32_t m_pending_work_items_count;
|
||||
std::vector<lldb::QueueItemSP> m_pending_items;
|
||||
lldb::addr_t m_dispatch_queue_t_addr; // address of libdispatch dispatch_queue_t for this Queue
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (Queue);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_Queue_h_
|
244
include/lldb/Target/QueueItem.h
Normal file
244
include/lldb/Target/QueueItem.h
Normal file
@ -0,0 +1,244 @@
|
||||
//===-- QueueItem.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_QueueItem_h_
|
||||
#define liblldb_QueueItem_h_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#include "lldb/Core/Address.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// QueueItem:
|
||||
// This class represents a work item enqueued on a libdispatch aka
|
||||
// Grand Central Dispatch (GCD) queue. Most often, this will be a
|
||||
// function or block.
|
||||
// "enqueued" here means that the work item has been added to a queue
|
||||
// but it has not yet started executing. When it is "dequeued",
|
||||
// execution of the item begins.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
||||
class QueueItem :
|
||||
public std::enable_shared_from_this<QueueItem>
|
||||
{
|
||||
public:
|
||||
|
||||
QueueItem (lldb::QueueSP queue_sp);
|
||||
|
||||
~QueueItem ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the kind of work item this is
|
||||
///
|
||||
/// @return
|
||||
/// The type of work item that this QueueItem object
|
||||
/// represents. eQueueItemKindUnknown may be returned.
|
||||
//------------------------------------------------------------------
|
||||
lldb::QueueItemKind
|
||||
GetKind () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the type of work item this is
|
||||
///
|
||||
/// @param [in] item_kind
|
||||
/// Set the kind of this work item object.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetKind (lldb::QueueItemKind item_kind);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the code address that will be executed when this work item
|
||||
/// is executed.
|
||||
///
|
||||
/// @return
|
||||
/// The address that will be invoked when this work item is
|
||||
/// executed. Not all types of QueueItems will have an
|
||||
/// address associated with them; check that the returned
|
||||
/// Address is valid, or check that the WorkItemKind is a
|
||||
/// kind that involves an address, such as eQueueItemKindFunction
|
||||
/// or eQueueItemKindBlock.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::Address &
|
||||
GetAddress ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the work item address for this object
|
||||
///
|
||||
/// @param [in] addr
|
||||
/// The address that will be invoked when this work item
|
||||
/// is executed.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetAddress (lldb_private::Address addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check if this QueueItem object is valid
|
||||
///
|
||||
/// If the weak pointer to the parent Queue cannot be revivified,
|
||||
/// it is invalid.
|
||||
///
|
||||
/// @return
|
||||
/// True if this object is valid.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
IsValid ()
|
||||
{
|
||||
return m_queue_wp.lock() != NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get an extended backtrace thread for this queue item, if available
|
||||
///
|
||||
/// If the backtrace/thread information was collected when this item
|
||||
/// was enqueued, this call will provide it.
|
||||
///
|
||||
/// @param [in] type
|
||||
/// The type of extended backtrace being requested, e.g. "libdispatch"
|
||||
/// or "pthread".
|
||||
///
|
||||
/// @return
|
||||
/// A thread shared pointer which will have a reference to an extended
|
||||
/// thread if one was available.
|
||||
//------------------------------------------------------------------
|
||||
lldb::ThreadSP
|
||||
GetExtendedBacktraceThread (ConstString type);
|
||||
|
||||
void
|
||||
SetItemThatEnqueuedThis (lldb::addr_t address_of_item)
|
||||
{
|
||||
m_item_that_enqueued_this_ref = address_of_item;
|
||||
}
|
||||
|
||||
lldb::addr_t
|
||||
GetItemThatEnqueuedThis ()
|
||||
{
|
||||
return m_item_that_enqueued_this_ref;
|
||||
}
|
||||
|
||||
void
|
||||
SetEnqueueingThreadID (lldb::tid_t tid)
|
||||
{
|
||||
m_enqueueing_thread_id = tid;
|
||||
}
|
||||
|
||||
lldb::tid_t
|
||||
GetEnqueueingThreadID ()
|
||||
{
|
||||
return m_enqueueing_thread_id;
|
||||
}
|
||||
|
||||
void
|
||||
SetEnqueueingQueueID (lldb::queue_id_t qid)
|
||||
{
|
||||
m_enqueueing_queue_id = qid;
|
||||
}
|
||||
|
||||
lldb::queue_id_t
|
||||
GetEnqueueingQueueID ()
|
||||
{
|
||||
return m_enqueueing_queue_id;
|
||||
}
|
||||
|
||||
void
|
||||
SetTargetQueueID (lldb::queue_id_t qid)
|
||||
{
|
||||
m_target_queue_id = qid;
|
||||
}
|
||||
|
||||
void
|
||||
SetStopID (uint32_t stop_id)
|
||||
{
|
||||
m_stop_id = stop_id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetStopID ()
|
||||
{
|
||||
return m_stop_id;
|
||||
}
|
||||
|
||||
void
|
||||
SetEnqueueingBacktrace (std::vector<lldb::addr_t> backtrace)
|
||||
{
|
||||
m_backtrace = backtrace;
|
||||
}
|
||||
|
||||
std::vector<lldb::addr_t> &
|
||||
GetEnqueueingBacktrace ()
|
||||
{
|
||||
return m_backtrace;
|
||||
}
|
||||
|
||||
void
|
||||
SetThreadLabel (std::string thread_name)
|
||||
{
|
||||
m_thread_label = thread_name;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetThreadLabel ()
|
||||
{
|
||||
return m_thread_label;
|
||||
}
|
||||
|
||||
void
|
||||
SetQueueLabel (std::string queue_name)
|
||||
{
|
||||
m_queue_label = queue_name;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetQueueLabel ()
|
||||
{
|
||||
return m_queue_label;
|
||||
}
|
||||
|
||||
void
|
||||
SetTargetQueueLabel (std::string queue_name)
|
||||
{
|
||||
m_target_queue_label = queue_name;
|
||||
}
|
||||
|
||||
protected:
|
||||
lldb::QueueWP m_queue_wp;
|
||||
lldb::QueueItemKind m_kind;
|
||||
lldb_private::Address m_address;
|
||||
|
||||
lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into libBacktraceRecording
|
||||
// to get the QueueItem that enqueued this item
|
||||
lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item
|
||||
lldb::queue_id_t m_enqueueing_queue_id; // Queue that enqueued this item, if it was a queue
|
||||
lldb::queue_id_t m_target_queue_id;
|
||||
uint32_t m_stop_id; // indicates when this backtrace was recorded in time
|
||||
std::vector<lldb::addr_t> m_backtrace;
|
||||
std::string m_thread_label;
|
||||
std::string m_queue_label;
|
||||
std::string m_target_queue_label;
|
||||
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
// For QueueItem only
|
||||
//------------------------------------------------------------------
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (QueueItem);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_QueueItem_h_
|
141
include/lldb/Target/QueueList.h
Normal file
141
include/lldb/Target/QueueList.h
Normal file
@ -0,0 +1,141 @@
|
||||
//===-- QueueList.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_QueueList_h_
|
||||
#define liblldb_QueueList_h_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/UserID.h"
|
||||
#include "lldb/Utility/Iterable.h"
|
||||
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// QueueList:
|
||||
// This is the container for libdispatch aka Grand Central Dispatch
|
||||
// Queue objects.
|
||||
//
|
||||
// Each Process will have a QueueList. When the process execution is
|
||||
// paused, the QueueList may be populated with Queues by the
|
||||
// SystemRuntime.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
class QueueList
|
||||
{
|
||||
friend class Process;
|
||||
|
||||
public:
|
||||
|
||||
QueueList (Process *process);
|
||||
|
||||
~QueueList ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the number of libdispatch queues that are available
|
||||
///
|
||||
/// @return
|
||||
/// The number of queues that are stored in the QueueList.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
GetSize();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the Queue at a given index number
|
||||
///
|
||||
/// @param [in] idx
|
||||
/// The index number (0-based) of the queue.
|
||||
/// @return
|
||||
/// The Queue at that index number.
|
||||
//------------------------------------------------------------------
|
||||
lldb::QueueSP
|
||||
GetQueueAtIndex (uint32_t idx);
|
||||
|
||||
typedef std::vector<lldb::QueueSP> collection;
|
||||
typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter> QueueIterable;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Iterate over the list of queues
|
||||
///
|
||||
/// @return
|
||||
/// An Iterable object which can be used to loop over the queues
|
||||
/// that exist.
|
||||
//------------------------------------------------------------------
|
||||
QueueIterable
|
||||
Queues ()
|
||||
{
|
||||
return QueueIterable(m_queues, m_mutex);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Clear out the list of queues from the QueueList
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
Clear();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Add a Queue to the QueueList
|
||||
///
|
||||
/// @param [in] queue
|
||||
/// Used by the SystemRuntime to populate the QueueList
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
AddQueue (lldb::QueueSP queue);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find a queue in the QueueList by QueueID
|
||||
///
|
||||
/// @param [in] qid
|
||||
/// The QueueID (same as returned by Thread::GetQueueID()) to find.
|
||||
///
|
||||
/// @return
|
||||
/// A QueueSP to the queue requested, if it is present in the QueueList.
|
||||
/// An empty QueueSP willbe returned if this queue was not found.
|
||||
//------------------------------------------------------------------
|
||||
lldb::QueueSP
|
||||
FindQueueByID (lldb::queue_id_t qid);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find a queue in the QueueList by IndexID
|
||||
///
|
||||
/// @param [in] index_id
|
||||
/// Find a queue by IndexID. This is an integer associated with each
|
||||
/// unique queue seen during a debug session and will not be reused
|
||||
/// for a different queue. Unlike the QueueID, a 64-bit value, this
|
||||
/// will tend to be an integral value like 1 or 7.
|
||||
///
|
||||
/// @return
|
||||
/// A QueueSP to the queue requested, if it is present in the QueueList.
|
||||
/// An empty QueueSP willbe returned if this queue was not found.
|
||||
//------------------------------------------------------------------
|
||||
lldb::QueueSP
|
||||
FindQueueByIndexID (uint32_t index_id);
|
||||
|
||||
lldb_private::Mutex &
|
||||
GetMutex ();
|
||||
|
||||
protected:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from Process can see and modify these
|
||||
//------------------------------------------------------------------
|
||||
Process *m_process; ///< The process that manages this queue list.
|
||||
uint32_t m_stop_id; ///< The process stop ID that this queue list is valid for.
|
||||
collection m_queues; ///< The queues for this process.
|
||||
Mutex m_mutex;
|
||||
|
||||
private:
|
||||
QueueList ();
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_QueueList_h_
|
109
include/lldb/Target/SectionLoadHistory.h
Normal file
109
include/lldb/Target/SectionLoadHistory.h
Normal file
@ -0,0 +1,109 @@
|
||||
//===-- SectionLoadHistory.h ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_SectionLoadHistory_h_
|
||||
#define liblldb_SectionLoadHistory_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <map>
|
||||
|
||||
// Project includes
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class SectionLoadHistory
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
// Pass eStopIDNow to any function that takes a stop ID to get
|
||||
// the current value.
|
||||
eStopIDNow = UINT32_MAX
|
||||
};
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
SectionLoadHistory () :
|
||||
m_stop_id_to_section_load_list(),
|
||||
m_mutex (Mutex::eMutexTypeRecursive)
|
||||
{
|
||||
}
|
||||
|
||||
~SectionLoadHistory()
|
||||
{
|
||||
// Call clear since this takes a lock and clears the section load list
|
||||
// in case another thread is currently using this section load list
|
||||
Clear();
|
||||
}
|
||||
|
||||
SectionLoadList &
|
||||
GetCurrentSectionLoadList ();
|
||||
|
||||
bool
|
||||
IsEmpty() const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
uint32_t
|
||||
GetLastStopID() const;
|
||||
|
||||
// Get the section load address given a process stop ID
|
||||
lldb::addr_t
|
||||
GetSectionLoadAddress (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp);
|
||||
|
||||
bool
|
||||
ResolveLoadAddress (uint32_t stop_id,
|
||||
lldb::addr_t load_addr,
|
||||
Address &so_addr);
|
||||
|
||||
bool
|
||||
SetSectionLoadAddress (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp,
|
||||
lldb::addr_t load_addr,
|
||||
bool warn_multiple = false);
|
||||
|
||||
// The old load address should be specified when unloading to ensure we get
|
||||
// the correct instance of the section as a shared library could be loaded
|
||||
// at more than one location.
|
||||
bool
|
||||
SetSectionUnloaded (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp,
|
||||
lldb::addr_t load_addr);
|
||||
|
||||
// Unload all instances of a section. This function can be used on systems
|
||||
// that don't support multiple copies of the same shared library to be
|
||||
// loaded at the same time.
|
||||
size_t
|
||||
SetSectionUnloaded (uint32_t stop_id,
|
||||
const lldb::SectionSP §ion_sp);
|
||||
|
||||
void
|
||||
Dump (Stream &s,
|
||||
Target *target);
|
||||
|
||||
protected:
|
||||
|
||||
SectionLoadList *
|
||||
GetSectionLoadListForStopID (uint32_t stop_id, bool read_only);
|
||||
|
||||
typedef std::map<uint32_t, lldb::SectionLoadListSP> StopIDToSectionLoadList;
|
||||
StopIDToSectionLoadList m_stop_id_to_section_load_list;
|
||||
mutable Mutex m_mutex;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (SectionLoadHistory);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_SectionLoadHistory_h_
|
@ -36,6 +36,8 @@ class SectionLoadList
|
||||
{
|
||||
}
|
||||
|
||||
SectionLoadList (const SectionLoadList& rhs);
|
||||
|
||||
~SectionLoadList()
|
||||
{
|
||||
// Call clear since this takes a lock and clears the section load list
|
||||
@ -43,6 +45,9 @@ class SectionLoadList
|
||||
Clear();
|
||||
}
|
||||
|
||||
void
|
||||
operator=(const SectionLoadList &rhs);
|
||||
|
||||
bool
|
||||
IsEmpty() const;
|
||||
|
||||
@ -79,9 +84,6 @@ class SectionLoadList
|
||||
addr_to_sect_collection m_addr_to_sect;
|
||||
sect_to_addr_collection m_sect_to_addr;
|
||||
mutable Mutex m_mutex;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (SectionLoadList);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
@ -20,9 +20,10 @@
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/ModuleList.h"
|
||||
#include "lldb/Core/PluginInterface.h"
|
||||
#include "lldb/Target/QueueList.h"
|
||||
#include "lldb/Target/QueueItem.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -103,6 +104,14 @@ class SystemRuntime :
|
||||
virtual void
|
||||
ModulesDidLoad(lldb_private::ModuleList &module_list);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Called before detaching from a process.
|
||||
///
|
||||
/// This will give a SystemRuntime plugin a chance to free any resources
|
||||
/// in the inferior process before we detach.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
Detach ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return a list of thread origin extended backtraces that may
|
||||
@ -160,6 +169,107 @@ class SystemRuntime :
|
||||
virtual lldb::ThreadSP
|
||||
GetExtendedBacktraceThread (lldb::ThreadSP thread, ConstString type);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the extended backtrace thread for a QueueItem
|
||||
///
|
||||
/// A QueueItem represents a function/block that will be executed on
|
||||
/// a libdispatch queue in the future, or it represents a function/block
|
||||
/// that is currently executing on a thread.
|
||||
///
|
||||
/// This method will report a thread backtrace of the function that
|
||||
/// enqueued it originally, if possible.
|
||||
///
|
||||
/// @param [in] queue_item_sp
|
||||
/// The QueueItem that we are getting an extended backtrace for.
|
||||
///
|
||||
/// @param [in] type
|
||||
/// The type of extended backtrace to fetch. The types supported
|
||||
/// are returned from SystemRuntime::GetExtendedBacktraceTypes.
|
||||
///
|
||||
/// @return
|
||||
/// If an extended backtrace is available, it is returned. Else
|
||||
/// an empty ThreadSP is returned.
|
||||
//------------------------------------------------------------------
|
||||
virtual lldb::ThreadSP
|
||||
GetExtendedBacktraceForQueueItem (lldb::QueueItemSP queue_item_sp, ConstString type)
|
||||
{
|
||||
return lldb::ThreadSP();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Populate the Process' QueueList with libdispatch / GCD queues that exist.
|
||||
///
|
||||
/// When process execution is paused, the SystemRuntime may be called to fill
|
||||
/// in the list of Queues that currently exist.
|
||||
///
|
||||
/// @param [out] queue_list
|
||||
/// This QueueList will be cleared, and any queues that currently exist
|
||||
/// will be added. An empty QueueList will be returned if no queues
|
||||
/// exist or if this Systemruntime does not support libdispatch queues.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
PopulateQueueList (lldb_private::QueueList &queue_list)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the queue name for a thread given a thread's dispatch_qaddr.
|
||||
///
|
||||
/// On systems using libdispatch queues, a thread may be associated with a queue.
|
||||
/// There will be a call to get the thread's dispatch_qaddr. At the dispatch_qaddr
|
||||
/// we will find the address of this thread's dispatch_queue_t structure.
|
||||
/// Given the address of the dispatch_queue_t structure for a thread,
|
||||
/// get the queue name and return it.
|
||||
///
|
||||
/// @param [in] dispatch_qaddr
|
||||
/// The address of the dispatch_queue_t structure for this thread.
|
||||
///
|
||||
/// @return
|
||||
/// The string of this queue's name. An empty string is returned if the
|
||||
/// name could not be found.
|
||||
//------------------------------------------------------------------
|
||||
virtual std::string
|
||||
GetQueueNameFromThreadQAddress (lldb::addr_t dispatch_qaddr)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the QueueID for the libdispatch queue given the thread's dispatch_qaddr.
|
||||
///
|
||||
/// On systems using libdispatch queues, a thread may be associated with a queue.
|
||||
/// There will be a call to get the thread's dispatch_qaddr. At the dispatch_qaddr
|
||||
/// we will find the address of this thread's dispatch_queue_t structure.
|
||||
/// Given the address of the dispatch_queue_t structure for a thread,
|
||||
/// get the queue ID and return it.
|
||||
///
|
||||
/// @param [in] dispatch_qaddr
|
||||
/// The address of the dispatch_queue_t structure for this thread.
|
||||
///
|
||||
/// @return
|
||||
/// The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID.
|
||||
//------------------------------------------------------------------
|
||||
virtual lldb::queue_id_t
|
||||
GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr)
|
||||
{
|
||||
return LLDB_INVALID_QUEUE_ID;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the pending work items for a libdispatch Queue
|
||||
///
|
||||
/// If this system/process is using libdispatch and the runtime can do so,
|
||||
/// retrieve the list of pending work items for the specified Queue and
|
||||
/// add it to the Queue.
|
||||
///
|
||||
/// @param [in] queue
|
||||
/// The queue of interest.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
PopulatePendingItemsForQueue (lldb_private::Queue *queue)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "lldb/Target/ABI.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
#include "lldb/Target/PathMappingList.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/SectionLoadHistory.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
@ -164,6 +164,9 @@ class TargetProperties : public Properties
|
||||
|
||||
bool
|
||||
GetUseFastStepping() const;
|
||||
|
||||
bool
|
||||
GetDisplayExpressionsInCrashlogs () const;
|
||||
|
||||
LoadScriptFromSymFile
|
||||
GetLoadScriptFromSymbolFile() const;
|
||||
@ -174,6 +177,11 @@ class TargetProperties : public Properties
|
||||
MemoryModuleLoadLevel
|
||||
GetMemoryModuleLoadLevel() const;
|
||||
|
||||
bool
|
||||
GetUserSpecifiedTrapHandlerNames (Args &args) const;
|
||||
|
||||
void
|
||||
SetUserSpecifiedTrapHandlerNames (const Args &args);
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<TargetProperties> TargetPropertiesSP;
|
||||
@ -526,6 +534,10 @@ class Target :
|
||||
|
||||
void
|
||||
Destroy();
|
||||
|
||||
Error
|
||||
Launch (Listener &listener,
|
||||
ProcessLaunchInfo &launch_info);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// This part handles the breakpoints.
|
||||
@ -630,7 +642,8 @@ class Target :
|
||||
CreateBreakpoint (lldb::SearchFilterSP &filter_sp,
|
||||
lldb::BreakpointResolverSP &resolver_sp,
|
||||
bool internal,
|
||||
bool request_hardware);
|
||||
bool request_hardware,
|
||||
bool resolve_indirect_symbols);
|
||||
|
||||
// Use this to create a watchpoint:
|
||||
lldb::WatchpointSP
|
||||
@ -1001,14 +1014,14 @@ class Target :
|
||||
SectionLoadList&
|
||||
GetSectionLoadList()
|
||||
{
|
||||
return m_section_load_list;
|
||||
return m_section_load_history.GetCurrentSectionLoadList();
|
||||
}
|
||||
|
||||
const SectionLoadList&
|
||||
GetSectionLoadList() const
|
||||
{
|
||||
return m_section_load_list;
|
||||
}
|
||||
// const SectionLoadList&
|
||||
// GetSectionLoadList() const
|
||||
// {
|
||||
// return const_cast<SectionLoadHistory *>(&m_section_load_history)->GetCurrentSectionLoadList();
|
||||
// }
|
||||
|
||||
static Target *
|
||||
GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr,
|
||||
@ -1048,6 +1061,26 @@ class Target :
|
||||
Error
|
||||
Install(ProcessLaunchInfo *launch_info);
|
||||
|
||||
|
||||
bool
|
||||
ResolveLoadAddress (lldb::addr_t load_addr,
|
||||
Address &so_addr,
|
||||
uint32_t stop_id = SectionLoadHistory::eStopIDNow);
|
||||
|
||||
bool
|
||||
SetSectionLoadAddress (const lldb::SectionSP §ion,
|
||||
lldb::addr_t load_addr,
|
||||
bool warn_multiple = false);
|
||||
|
||||
bool
|
||||
SetSectionUnloaded (const lldb::SectionSP §ion_sp);
|
||||
|
||||
bool
|
||||
SetSectionUnloaded (const lldb::SectionSP §ion_sp, lldb::addr_t load_addr);
|
||||
|
||||
void
|
||||
ClearAllLoadedSections ();
|
||||
|
||||
// Since expressions results can persist beyond the lifetime of a process,
|
||||
// and the const expression results are available after a process is gone,
|
||||
// we provide a way for expressions to be evaluated from the Target itself.
|
||||
@ -1144,7 +1177,7 @@ class Target :
|
||||
std::unique_ptr<ThreadSpec> m_thread_spec_ap;
|
||||
bool m_active;
|
||||
|
||||
// Use AddStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands,
|
||||
// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands,
|
||||
// and SetSpecifier to set the specifier shared pointer (can be null, that will match anything.)
|
||||
StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid);
|
||||
friend class Target;
|
||||
@ -1153,8 +1186,8 @@ class Target :
|
||||
|
||||
// Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to it in new_hook.
|
||||
// Returns the id of the new hook.
|
||||
lldb::user_id_t
|
||||
AddStopHook (StopHookSP &new_hook);
|
||||
StopHookSP
|
||||
CreateStopHook ();
|
||||
|
||||
void
|
||||
RunStopHooks ();
|
||||
@ -1250,7 +1283,7 @@ class Target :
|
||||
Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
|
||||
ArchSpec m_arch;
|
||||
ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded).
|
||||
SectionLoadList m_section_load_list;
|
||||
SectionLoadHistory m_section_load_history;
|
||||
BreakpointList m_breakpoint_list;
|
||||
BreakpointList m_internal_breakpoint_list;
|
||||
lldb::BreakpointSP m_last_created_breakpoint;
|
||||
@ -1260,7 +1293,6 @@ class Target :
|
||||
// we can correctly tear down everything that we need to, so the only
|
||||
// class that knows about the process lifespan is this target class.
|
||||
lldb::ProcessSP m_process_sp;
|
||||
bool m_valid;
|
||||
lldb::SearchFilterSP m_search_filter_sp;
|
||||
PathMappingList m_image_search_paths;
|
||||
std::unique_ptr<ClangASTContext> m_scratch_ast_context_ap;
|
||||
@ -1273,8 +1305,8 @@ class Target :
|
||||
typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection;
|
||||
StopHookCollection m_stop_hooks;
|
||||
lldb::user_id_t m_stop_hook_next_id;
|
||||
bool m_valid;
|
||||
bool m_suppress_stop_hooks;
|
||||
bool m_suppress_synthetic_value;
|
||||
|
||||
static void
|
||||
ImageSearchPathsChanged (const PathMappingList &path_list,
|
||||
|
@ -44,6 +44,9 @@ class ThreadProperties : public Properties
|
||||
const RegularExpression *
|
||||
GetSymbolsToAvoidRegexp();
|
||||
|
||||
FileSpecList &
|
||||
GetLibrariesToAvoid() const;
|
||||
|
||||
bool
|
||||
GetTraceEnabledState() const;
|
||||
};
|
||||
@ -409,6 +412,55 @@ class Thread :
|
||||
void
|
||||
DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default implementation for stepping into.
|
||||
///
|
||||
/// This function is designed to be used by commands where the
|
||||
/// process is publicly stopped.
|
||||
///
|
||||
/// @param[in] source_step
|
||||
/// If true and the frame has debug info, then do a source level
|
||||
/// step in, else do a single instruction step in.
|
||||
///
|
||||
/// @param[in] avoid_code_without_debug_info
|
||||
/// If \a true, then avoid stepping into code that doesn't have
|
||||
/// debug info, else step into any code regardless of wether it
|
||||
/// has debug info.
|
||||
///
|
||||
/// @return
|
||||
/// An error that describes anything that went wrong
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
StepIn (bool source_step,
|
||||
bool avoid_code_without_debug_info);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default implementation for stepping over.
|
||||
///
|
||||
/// This function is designed to be used by commands where the
|
||||
/// process is publicly stopped.
|
||||
///
|
||||
/// @param[in] source_step
|
||||
/// If true and the frame has debug info, then do a source level
|
||||
/// step over, else do a single instruction step over.
|
||||
///
|
||||
/// @return
|
||||
/// An error that describes anything that went wrong
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
StepOver (bool source_step);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default implementation for stepping out.
|
||||
///
|
||||
/// This function is designed to be used by commands where the
|
||||
/// process is publicly stopped.
|
||||
///
|
||||
/// @return
|
||||
/// An error that describes anything that went wrong
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
StepOut ();
|
||||
//------------------------------------------------------------------
|
||||
/// Retrieves the per-thread data area.
|
||||
/// Most OSs maintain a per-thread pointer (e.g. the FS register on
|
||||
|
@ -45,6 +45,8 @@ friend class Process;
|
||||
void
|
||||
AddThread (const lldb::ThreadSP &thread_sp);
|
||||
|
||||
void
|
||||
InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx);
|
||||
// Return the selected thread if there is one. Otherwise, return the thread
|
||||
// selected at index 0.
|
||||
lldb::ThreadSP
|
||||
|
@ -73,7 +73,7 @@ class ThreadPlanStepInRange :
|
||||
SetFlagsToDefault ();
|
||||
|
||||
bool
|
||||
FrameMatchesAvoidRegexp ();
|
||||
FrameMatchesAvoidCriteria ();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -17,10 +17,11 @@
|
||||
namespace lldb_private {
|
||||
|
||||
class UnwindAssembly :
|
||||
public std::enable_shared_from_this<UnwindAssembly>,
|
||||
public PluginInterface
|
||||
{
|
||||
public:
|
||||
static UnwindAssembly*
|
||||
static lldb::UnwindAssemblySP
|
||||
FindPlugin (const ArchSpec &arch);
|
||||
|
||||
virtual
|
||||
|
@ -147,9 +147,14 @@ template <typename C, typename E, E (*A)(typename C::const_iterator &)> class Ad
|
||||
return m_iter >= rhs.m_iter;
|
||||
}
|
||||
|
||||
friend AdaptedConstIterator operator+(typename BackingIterator::difference_type, AdaptedConstIterator &);
|
||||
friend typename BackingIterator::difference_type operator-(AdaptedConstIterator &, AdaptedConstIterator &);
|
||||
friend void swap(AdaptedConstIterator &, AdaptedConstIterator &);
|
||||
template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
|
||||
friend AdaptedConstIterator<C1, E1, A1> operator+(typename C1::const_iterator::difference_type, AdaptedConstIterator<C1, E1, A1> &);
|
||||
|
||||
template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
|
||||
friend typename C1::const_iterator::difference_type operator-(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &);
|
||||
|
||||
template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
|
||||
friend void swap(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &);
|
||||
};
|
||||
|
||||
template <typename C, typename E, E (*A)(typename C::const_iterator &)>
|
||||
|
@ -726,6 +726,19 @@ namespace lldb {
|
||||
eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX,
|
||||
} FilePermissions;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Queue work item types
|
||||
//
|
||||
// The different types of work that can be enqueued on a libdispatch
|
||||
// aka Grand Central Dispatch (GCD) queue.
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum QueueItemKind
|
||||
{
|
||||
eQueueItemKindUnknown = 0,
|
||||
eQueueItemKindFunction,
|
||||
eQueueItemKindBlock
|
||||
} QueueItemKind;
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
|
||||
|
@ -82,6 +82,7 @@ class Disassembler;
|
||||
struct DumpValueObjectOptions;
|
||||
class DynamicLibrary;
|
||||
class DynamicLoader;
|
||||
class Editline;
|
||||
class EmulateInstruction;
|
||||
class Error;
|
||||
class EvaluateExpressionOptions;
|
||||
@ -102,9 +103,9 @@ class FuncUnwinders;
|
||||
class Function;
|
||||
class FunctionInfo;
|
||||
class InlineFunctionInfo;
|
||||
class InputReader;
|
||||
class Instruction;
|
||||
class InstructionList;
|
||||
class IOHandler;
|
||||
class IRExecutionUnit;
|
||||
class LanguageRuntime;
|
||||
class SystemRuntime;
|
||||
@ -181,6 +182,8 @@ class SearchFilter;
|
||||
class Section;
|
||||
class SectionImpl;
|
||||
class SectionList;
|
||||
class SectionLoadHistory;
|
||||
class SectionLoadList;
|
||||
class Settings;
|
||||
class SourceManager;
|
||||
class SourceManagerImpl;
|
||||
@ -214,6 +217,9 @@ class TypeFilterImpl;
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
class ScriptedSyntheticChildren;
|
||||
#endif
|
||||
class Queue;
|
||||
class QueueItem;
|
||||
class QueueImpl;
|
||||
class Target;
|
||||
class TargetList;
|
||||
class Thread;
|
||||
@ -297,8 +303,8 @@ namespace lldb {
|
||||
typedef std::shared_ptr<lldb_private::Function> FunctionSP;
|
||||
typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP;
|
||||
typedef std::shared_ptr<lldb_private::InlineFunctionInfo> InlineFunctionInfoSP;
|
||||
typedef std::shared_ptr<lldb_private::InputReader> InputReaderSP;
|
||||
typedef std::shared_ptr<lldb_private::Instruction> InstructionSP;
|
||||
typedef std::shared_ptr<lldb_private::IOHandler> IOHandlerSP;
|
||||
typedef std::shared_ptr<lldb_private::LanguageRuntime> LanguageRuntimeSP;
|
||||
typedef std::shared_ptr<lldb_private::SystemRuntime> SystemRuntimeSP;
|
||||
typedef std::shared_ptr<lldb_private::LineTable> LineTableSP;
|
||||
@ -334,12 +340,16 @@ namespace lldb {
|
||||
typedef std::shared_ptr<lldb_private::RegisterCheckpoint> RegisterCheckpointSP;
|
||||
typedef std::shared_ptr<lldb_private::RegisterContext> RegisterContextSP;
|
||||
typedef std::shared_ptr<lldb_private::RegularExpression> RegularExpressionSP;
|
||||
typedef std::shared_ptr<lldb_private::Queue> QueueSP;
|
||||
typedef std::weak_ptr<lldb_private::Queue> QueueWP;
|
||||
typedef std::shared_ptr<lldb_private::QueueItem> QueueItemSP;
|
||||
typedef std::shared_ptr<lldb_private::ScriptInterpreterObject> ScriptInterpreterObjectSP;
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP;
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
typedef std::shared_ptr<lldb_private::Section> SectionSP;
|
||||
typedef std::weak_ptr<lldb_private::Section> SectionWP;
|
||||
typedef std::shared_ptr<lldb_private::SectionLoadList> SectionLoadListSP;
|
||||
typedef std::shared_ptr<lldb_private::SearchFilter> SearchFilterSP;
|
||||
typedef std::shared_ptr<lldb_private::Settings> SettingsSP;
|
||||
typedef std::shared_ptr<lldb_private::StackFrame> StackFrameSP;
|
||||
@ -349,6 +359,7 @@ namespace lldb {
|
||||
typedef std::shared_ptr<lldb_private::StoppointLocation> StoppointLocationSP;
|
||||
typedef std::shared_ptr<lldb_private::Stream> StreamSP;
|
||||
typedef std::weak_ptr<lldb_private::Stream> StreamWP;
|
||||
typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP;
|
||||
typedef std::shared_ptr<lldb_private::StringSummaryFormat> StringTypeSummaryImplSP;
|
||||
typedef std::shared_ptr<lldb_private::SymbolFile> SymbolFileSP;
|
||||
typedef std::shared_ptr<lldb_private::SymbolFileType> SymbolFileTypeSP;
|
||||
@ -373,6 +384,7 @@ namespace lldb {
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
typedef std::shared_ptr<lldb_private::ScriptedSyntheticChildren> ScriptedSyntheticChildrenSP;
|
||||
#endif
|
||||
typedef std::shared_ptr<lldb_private::UnwindAssembly> UnwindAssemblySP;
|
||||
typedef std::shared_ptr<lldb_private::UnwindPlan> UnwindPlanSP;
|
||||
typedef lldb_private::SharingPtr<lldb_private::ValueObject> ValueObjectSP;
|
||||
typedef std::shared_ptr<lldb_private::Value> ValueSP;
|
||||
|
@ -117,7 +117,9 @@ typedef enum PathType
|
||||
ePathTypeHeaderDir, // Find LLDB header file directory
|
||||
ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory
|
||||
ePathTypeLLDBSystemPlugins, // System plug-ins directory
|
||||
ePathTypeLLDBUserPlugins // User plug-ins directory
|
||||
ePathTypeLLDBUserPlugins, // User plug-ins directory
|
||||
ePathTypeLLDBTempSystemDir // The LLDB temp directory for this system
|
||||
|
||||
} PathType;
|
||||
|
||||
|
||||
@ -251,6 +253,15 @@ typedef enum MemoryModuleLoadLevel {
|
||||
} MemoryModuleLoadLevel;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Result enums for when reading multiple lines from IOHandlers
|
||||
//----------------------------------------------------------------------
|
||||
enum class LineStatus {
|
||||
Success, // The line that was just edited if good and should be added to the lines
|
||||
Error, // There is an error with the current line and it needs to be re-edited before it can be accepted
|
||||
Done // Lines are complete
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define LIBLLDB_LOG_MMAP (1u << 23)
|
||||
#define LIBLLDB_LOG_OS (1u << 24)
|
||||
#define LIBLLDB_LOG_PLATFORM (1u << 25)
|
||||
#define LIBLLDB_LOG_SYSTEM_RUNTIME (1u << 26)
|
||||
#define LIBLLDB_LOG_ALL (UINT32_MAX)
|
||||
#define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\
|
||||
LIBLLDB_LOG_THREAD |\
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/ThreadSpec.h"
|
||||
|
@ -107,6 +107,22 @@ SBCommandInterpreter::AliasExists (const char *cmd)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SBCommandInterpreter::IsActive ()
|
||||
{
|
||||
if (m_opaque_ptr)
|
||||
return m_opaque_ptr->IsActive ();
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *
|
||||
SBCommandInterpreter::GetIOHandlerControlSequence(char ch)
|
||||
{
|
||||
if (m_opaque_ptr)
|
||||
return m_opaque_ptr->GetDebugger().GetTopIOHandlerControlSequence (ch).GetCString();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lldb::ReturnStatus
|
||||
SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history)
|
||||
{
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBEvent.h"
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBProcess.h"
|
||||
#include "lldb/API/SBSourceManager.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
@ -37,6 +36,7 @@
|
||||
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/DataFormatters/DataVisualization.h"
|
||||
#include "lldb/Host/DynamicLibrary.h"
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
@ -49,6 +49,29 @@ using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
||||
SBInputReader::SBInputReader()
|
||||
{
|
||||
}
|
||||
SBInputReader::~SBInputReader()
|
||||
{
|
||||
}
|
||||
|
||||
SBError
|
||||
SBInputReader::Initialize(lldb::SBDebugger& sb_debugger, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool)
|
||||
{
|
||||
return SBError();
|
||||
}
|
||||
|
||||
void
|
||||
SBInputReader::SetIsDone(bool)
|
||||
{
|
||||
}
|
||||
bool
|
||||
SBInputReader::IsActive() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static lldb::DynamicLibrarySP
|
||||
LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& error)
|
||||
{
|
||||
@ -111,7 +134,7 @@ SBDebugger::Clear ()
|
||||
log->Printf ("SBDebugger(%p)::Clear ()", m_opaque_sp.get());
|
||||
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->CleanUpInputReaders ();
|
||||
m_opaque_sp->ClearIOHandlers ();
|
||||
|
||||
m_opaque_sp.reset();
|
||||
}
|
||||
@ -309,7 +332,11 @@ FILE *
|
||||
SBDebugger::GetInputFileHandle ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetInputFile().GetStream();
|
||||
{
|
||||
StreamFileSP stream_file_sp (m_opaque_sp->GetInputFile());
|
||||
if (stream_file_sp)
|
||||
return stream_file_sp->GetFile().GetStream();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -317,7 +344,11 @@ FILE *
|
||||
SBDebugger::GetOutputFileHandle ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetOutputFile().GetStream();
|
||||
{
|
||||
StreamFileSP stream_file_sp (m_opaque_sp->GetOutputFile());
|
||||
if (stream_file_sp)
|
||||
return stream_file_sp->GetFile().GetStream();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -325,7 +356,12 @@ FILE *
|
||||
SBDebugger::GetErrorFileHandle ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetErrorFile().GetStream();
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
StreamFileSP stream_file_sp (m_opaque_sp->GetErrorFile());
|
||||
if (stream_file_sp)
|
||||
return stream_file_sp->GetFile().GetStream();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -885,17 +921,17 @@ SBDebugger::DispatchInput (void* baton, const void *data, size_t data_len)
|
||||
void
|
||||
SBDebugger::DispatchInput (const void *data, size_t data_len)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")",
|
||||
m_opaque_sp.get(),
|
||||
(int) data_len,
|
||||
(const char *) data,
|
||||
(uint64_t)data_len);
|
||||
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->DispatchInput ((const char *) data, data_len);
|
||||
// Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
//
|
||||
// if (log)
|
||||
// log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")",
|
||||
// m_opaque_sp.get(),
|
||||
// (int) data_len,
|
||||
// (const char *) data,
|
||||
// (uint64_t)data_len);
|
||||
//
|
||||
// if (m_opaque_sp)
|
||||
// m_opaque_sp->DispatchInput ((const char *) data, data_len);
|
||||
}
|
||||
|
||||
void
|
||||
@ -911,54 +947,18 @@ SBDebugger::DispatchInputEndOfFile ()
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->DispatchInputEndOfFile ();
|
||||
}
|
||||
|
||||
bool
|
||||
SBDebugger::InputReaderIsTopReader (const lldb::SBInputReader &reader)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::InputReaderIsTopReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
|
||||
|
||||
if (m_opaque_sp && reader.IsValid())
|
||||
{
|
||||
InputReaderSP reader_sp (*reader);
|
||||
return m_opaque_sp->InputReaderIsTopReader (reader_sp);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SBDebugger::PushInputReader (SBInputReader &reader)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::PushInputReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
|
||||
|
||||
if (m_opaque_sp && reader.IsValid())
|
||||
{
|
||||
TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
|
||||
Mutex::Locker api_locker;
|
||||
if (target_sp)
|
||||
api_locker.Lock(target_sp->GetAPIMutex());
|
||||
InputReaderSP reader_sp(*reader);
|
||||
m_opaque_sp->PushInputReader (reader_sp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SBDebugger::NotifyTopInputReader (InputReaderAction notification)
|
||||
SBDebugger::RunCommandInterpreter (bool auto_handle_events,
|
||||
bool spawn_thread)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::NotifyTopInputReader (%d)", m_opaque_sp.get(), notification);
|
||||
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->NotifyTopInputReader (notification);
|
||||
m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events, spawn_thread);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1050,7 +1050,7 @@ SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger
|
||||
if (!value_str.empty())
|
||||
{
|
||||
StringList string_list;
|
||||
string_list.SplitIntoLines(value_str.c_str(), value_str.size());
|
||||
string_list.SplitIntoLines(value_str);
|
||||
return SBStringList(&string_list);
|
||||
}
|
||||
}
|
||||
|
@ -1386,20 +1386,22 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option
|
||||
frame = exe_ctx.GetFramePtr();
|
||||
if (frame)
|
||||
{
|
||||
#ifdef LLDB_CONFIGURATION_DEBUG
|
||||
StreamString frame_description;
|
||||
frame->DumpUsingSettingsFormat (&frame_description);
|
||||
Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
|
||||
expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
|
||||
#endif
|
||||
exe_results = target->EvaluateExpression (expr,
|
||||
if (target->GetDisplayExpressionsInCrashlogs())
|
||||
{
|
||||
StreamString frame_description;
|
||||
frame->DumpUsingSettingsFormat (&frame_description);
|
||||
Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
|
||||
expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
|
||||
}
|
||||
|
||||
exe_results = target->EvaluateExpression (expr,
|
||||
frame,
|
||||
expr_value_sp,
|
||||
options.ref());
|
||||
expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
|
||||
#ifdef LLDB_CONFIGURATION_DEBUG
|
||||
Host::SetCrashDescription (NULL);
|
||||
#endif
|
||||
|
||||
if (target->GetDisplayExpressionsInCrashlogs())
|
||||
Host::SetCrashDescription (NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,216 +0,0 @@
|
||||
//===-- SBInputReader.cpp ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
SBInputReader::SBInputReader () :
|
||||
m_opaque_sp (),
|
||||
m_callback_function (NULL),
|
||||
m_callback_baton (NULL)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
SBInputReader::SBInputReader (const lldb::InputReaderSP &reader_sp) :
|
||||
m_opaque_sp (reader_sp)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBInputReader::SBInputReader (reader_sp=%p) => SBInputReader(%p)", reader_sp.get(),
|
||||
m_opaque_sp.get());
|
||||
}
|
||||
|
||||
SBInputReader::SBInputReader (const SBInputReader &rhs) :
|
||||
m_opaque_sp (rhs.m_opaque_sp)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf("SBInputReader::SBInputReader (rhs.sp=%p) => SBInputReader(%p)",
|
||||
rhs.m_opaque_sp.get(), m_opaque_sp.get());
|
||||
}
|
||||
|
||||
SBInputReader::~SBInputReader ()
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
SBInputReader::PrivateCallback
|
||||
(
|
||||
void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len
|
||||
)
|
||||
{
|
||||
SBInputReader *sb_reader = (SBInputReader *)baton;
|
||||
return sb_reader->m_callback_function (sb_reader->m_callback_baton,
|
||||
sb_reader,
|
||||
notification,
|
||||
bytes,
|
||||
bytes_len);
|
||||
}
|
||||
|
||||
SBError
|
||||
SBInputReader::Initialize
|
||||
(
|
||||
SBDebugger &debugger,
|
||||
Callback callback_function,
|
||||
void *callback_baton,
|
||||
lldb::InputReaderGranularity granularity,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo
|
||||
)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf("SBInputReader(%p)::Initialize (SBDebugger(%p), callback_function=%p, callback_baton=%p, "
|
||||
"granularity=%s, end_token=\"%s\", prompt=\"%s\", echo=%i)",
|
||||
m_opaque_sp.get(),
|
||||
debugger.get(),
|
||||
callback_function,
|
||||
callback_baton,
|
||||
InputReader::GranularityAsCString (granularity), end_token, prompt,
|
||||
echo);
|
||||
|
||||
SBError sb_error;
|
||||
m_opaque_sp.reset (new InputReader (debugger.ref()));
|
||||
|
||||
m_callback_function = callback_function;
|
||||
m_callback_baton = callback_baton;
|
||||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
sb_error.SetError (m_opaque_sp->Initialize (SBInputReader::PrivateCallback,
|
||||
this,
|
||||
granularity,
|
||||
end_token,
|
||||
prompt,
|
||||
echo));
|
||||
}
|
||||
|
||||
if (sb_error.Fail())
|
||||
{
|
||||
m_opaque_sp.reset ();
|
||||
m_callback_function = NULL;
|
||||
m_callback_baton = NULL;
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
SBStream sstr;
|
||||
sb_error.GetDescription (sstr);
|
||||
log->Printf ("SBInputReader(%p)::Initialize (...) => SBError(%p): %s", m_opaque_sp.get(),
|
||||
sb_error.get(), sstr.GetData());
|
||||
}
|
||||
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
bool
|
||||
SBInputReader::IsValid () const
|
||||
{
|
||||
return (m_opaque_sp.get() != NULL);
|
||||
}
|
||||
|
||||
const SBInputReader &
|
||||
SBInputReader::operator = (const SBInputReader &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
m_opaque_sp = rhs.m_opaque_sp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputReader *
|
||||
SBInputReader::operator->() const
|
||||
{
|
||||
return m_opaque_sp.get();
|
||||
}
|
||||
|
||||
lldb::InputReaderSP &
|
||||
SBInputReader::operator *()
|
||||
{
|
||||
return m_opaque_sp;
|
||||
}
|
||||
|
||||
const lldb::InputReaderSP &
|
||||
SBInputReader::operator *() const
|
||||
{
|
||||
return m_opaque_sp;
|
||||
}
|
||||
|
||||
InputReader *
|
||||
SBInputReader::get() const
|
||||
{
|
||||
return m_opaque_sp.get();
|
||||
}
|
||||
|
||||
InputReader &
|
||||
SBInputReader::ref() const
|
||||
{
|
||||
assert (m_opaque_sp.get());
|
||||
return *m_opaque_sp;
|
||||
}
|
||||
|
||||
bool
|
||||
SBInputReader::IsDone () const
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->IsDone();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SBInputReader::SetIsDone (bool value)
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->SetIsDone (value);
|
||||
}
|
||||
|
||||
bool
|
||||
SBInputReader::IsActive () const
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
bool ret_value = false;
|
||||
if (m_opaque_sp)
|
||||
ret_value = m_opaque_sp->IsActive();
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBInputReader(%p)::IsActive () => %i", m_opaque_sp.get(), ret_value);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
InputReaderGranularity
|
||||
SBInputReader::GetGranularity ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetGranularity();
|
||||
else
|
||||
return eInputReaderGranularityInvalid;
|
||||
}
|
@ -69,7 +69,7 @@ SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) :
|
||||
{
|
||||
Target &target = process_sp->GetTarget();
|
||||
bool changed = false;
|
||||
m_opaque_sp->SetLoadAddress(target, 0, changed);
|
||||
m_opaque_sp->SetLoadAddress(target, 0, true, changed);
|
||||
target.GetImages().Append(m_opaque_sp);
|
||||
}
|
||||
}
|
||||
@ -579,6 +579,23 @@ SBModule::FindTypes (const char *type)
|
||||
return retval;
|
||||
}
|
||||
|
||||
lldb::SBType
|
||||
SBModule::GetTypeByID (lldb::user_id_t uid)
|
||||
{
|
||||
ModuleSP module_sp (GetSP ());
|
||||
if (module_sp)
|
||||
{
|
||||
SymbolVendor* vendor = module_sp->GetSymbolVendor();
|
||||
if (vendor)
|
||||
{
|
||||
Type *type_ptr = vendor->ResolveTypeUID(uid);
|
||||
if (type_ptr)
|
||||
return SBType(type_ptr->shared_from_this());
|
||||
}
|
||||
}
|
||||
return SBType();
|
||||
}
|
||||
|
||||
lldb::SBTypeList
|
||||
SBModule::GetTypes (uint32_t type_mask)
|
||||
{
|
||||
|
@ -534,6 +534,53 @@ SBProcess::GetThreadAtIndex (size_t index)
|
||||
return sb_thread;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SBProcess::GetNumQueues ()
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
uint32_t num_queues = 0;
|
||||
ProcessSP process_sp(GetSP());
|
||||
if (process_sp)
|
||||
{
|
||||
Process::StopLocker stop_locker;
|
||||
|
||||
Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
|
||||
num_queues = process_sp->GetQueueList().GetSize();
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBProcess(%p)::GetNumQueues () => %d", process_sp.get(), num_queues);
|
||||
|
||||
return num_queues;
|
||||
}
|
||||
|
||||
SBQueue
|
||||
SBProcess::GetQueueAtIndex (size_t index)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
SBQueue sb_queue;
|
||||
QueueSP queue_sp;
|
||||
ProcessSP process_sp(GetSP());
|
||||
if (process_sp)
|
||||
{
|
||||
Process::StopLocker stop_locker;
|
||||
Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
|
||||
queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index);
|
||||
sb_queue.SetQueue (queue_sp);
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)",
|
||||
process_sp.get(), (uint32_t) index, queue_sp.get());
|
||||
}
|
||||
|
||||
return sb_queue;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
SBProcess::GetStopID(bool include_expression_stops)
|
||||
{
|
||||
|
368
source/API/SBQueue.cpp
Normal file
368
source/API/SBQueue.cpp
Normal file
@ -0,0 +1,368 @@
|
||||
//===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/lldb-python.h"
|
||||
|
||||
#include "lldb/API/SBQueue.h"
|
||||
|
||||
#include "lldb/API/SBProcess.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Queue.h"
|
||||
#include "lldb/Target/QueueItem.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
namespace lldb_private
|
||||
{
|
||||
|
||||
class QueueImpl
|
||||
{
|
||||
public:
|
||||
QueueImpl () :
|
||||
m_queue_wp(),
|
||||
m_threads(),
|
||||
m_thread_list_fetched(false),
|
||||
m_pending_items(),
|
||||
m_pending_items_fetched(false)
|
||||
{
|
||||
}
|
||||
|
||||
QueueImpl (const lldb::QueueSP &queue_sp) :
|
||||
m_queue_wp(),
|
||||
m_threads(),
|
||||
m_thread_list_fetched(false),
|
||||
m_pending_items(),
|
||||
m_pending_items_fetched(false)
|
||||
{
|
||||
m_queue_wp = queue_sp;
|
||||
}
|
||||
|
||||
QueueImpl (const QueueImpl &rhs)
|
||||
{
|
||||
if (&rhs == this)
|
||||
return;
|
||||
m_queue_wp = rhs.m_queue_wp;
|
||||
m_threads = rhs.m_threads;
|
||||
m_thread_list_fetched = rhs.m_thread_list_fetched;
|
||||
m_pending_items = rhs.m_pending_items;
|
||||
m_pending_items_fetched = rhs.m_pending_items_fetched;
|
||||
}
|
||||
|
||||
~QueueImpl ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
IsValid ()
|
||||
{
|
||||
return m_queue_wp.lock() != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Clear ()
|
||||
{
|
||||
m_queue_wp.reset();
|
||||
m_thread_list_fetched = false;
|
||||
m_threads.clear();
|
||||
m_pending_items_fetched = false;
|
||||
m_pending_items.clear();
|
||||
}
|
||||
|
||||
void
|
||||
SetQueue (const lldb::QueueSP &queue_sp)
|
||||
{
|
||||
Clear();
|
||||
m_queue_wp = queue_sp;
|
||||
}
|
||||
|
||||
lldb::queue_id_t
|
||||
GetQueueID () const
|
||||
{
|
||||
lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
|
||||
lldb::QueueSP queue_sp = m_queue_wp.lock();
|
||||
if (queue_sp)
|
||||
{
|
||||
result = queue_sp->GetID();
|
||||
}
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, this, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetIndexID () const
|
||||
{
|
||||
uint32_t result = LLDB_INVALID_INDEX32;
|
||||
lldb::QueueSP queue_sp = m_queue_wp.lock();
|
||||
if (queue_sp)
|
||||
{
|
||||
result = queue_sp->GetIndexID();
|
||||
}
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf ("SBQueueImpl(%p)::GetIndexID () => %d", this, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *
|
||||
GetName () const
|
||||
{
|
||||
const char *name = NULL;
|
||||
lldb::QueueSP queue_sp = m_queue_wp.lock ();
|
||||
if (queue_sp.get())
|
||||
{
|
||||
name = queue_sp->GetName();
|
||||
}
|
||||
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf ("SBQueueImpl(%p)::GetName () => %s", this, name ? name : "NULL");
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
FetchThreads ()
|
||||
{
|
||||
if (m_thread_list_fetched == false)
|
||||
{
|
||||
lldb::QueueSP queue_sp = m_queue_wp.lock();
|
||||
if (queue_sp)
|
||||
{
|
||||
Process::StopLocker stop_locker;
|
||||
if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
|
||||
{
|
||||
const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
|
||||
m_thread_list_fetched = true;
|
||||
const uint32_t num_threads = thread_list.size();
|
||||
for (uint32_t idx = 0; idx < num_threads; ++idx)
|
||||
{
|
||||
ThreadSP thread_sp = thread_list[idx];
|
||||
if (thread_sp && thread_sp->IsValid())
|
||||
{
|
||||
m_threads.push_back (thread_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FetchItems ()
|
||||
{
|
||||
if (m_pending_items_fetched == false)
|
||||
{
|
||||
QueueSP queue_sp = m_queue_wp.lock();
|
||||
if (queue_sp)
|
||||
{
|
||||
Process::StopLocker stop_locker;
|
||||
if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
|
||||
{
|
||||
const std::vector<QueueItemSP> queue_items(queue_sp->GetPendingItems());
|
||||
m_pending_items_fetched = true;
|
||||
const uint32_t num_pending_items = queue_items.size();
|
||||
for (uint32_t idx = 0; idx < num_pending_items; ++idx)
|
||||
{
|
||||
QueueItemSP item = queue_items[idx];
|
||||
if (item && item->IsValid())
|
||||
{
|
||||
m_pending_items.push_back (item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetNumThreads ()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
FetchThreads();
|
||||
if (m_thread_list_fetched)
|
||||
{
|
||||
result = m_threads.size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBThread
|
||||
GetThreadAtIndex (uint32_t idx)
|
||||
{
|
||||
FetchThreads();
|
||||
|
||||
SBThread sb_thread;
|
||||
QueueSP queue_sp = m_queue_wp.lock();
|
||||
if (queue_sp && idx < m_threads.size())
|
||||
{
|
||||
ProcessSP process_sp = queue_sp->GetProcess();
|
||||
if (process_sp)
|
||||
{
|
||||
ThreadSP thread_sp = m_threads[idx].lock();
|
||||
if (thread_sp)
|
||||
{
|
||||
sb_thread.SetThread (thread_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb_thread;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
GetNumPendingItems ()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
FetchItems();
|
||||
|
||||
if (m_pending_items_fetched)
|
||||
{
|
||||
result = m_pending_items.size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBQueueItem
|
||||
GetPendingItemAtIndex (uint32_t idx)
|
||||
{
|
||||
SBQueueItem result;
|
||||
FetchItems();
|
||||
if (m_pending_items_fetched && idx < m_pending_items.size())
|
||||
{
|
||||
result.SetQueueItem (m_pending_items[idx]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
lldb::SBProcess
|
||||
GetProcess ()
|
||||
{
|
||||
SBProcess result;
|
||||
QueueSP queue_sp = m_queue_wp.lock();
|
||||
if (queue_sp)
|
||||
{
|
||||
result.SetSP (queue_sp->GetProcess());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
lldb::QueueWP m_queue_wp;
|
||||
std::vector<lldb::ThreadWP> m_threads; // threads currently executing this queue's items
|
||||
bool m_thread_list_fetched; // have we tried to fetch the threads list already?
|
||||
std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
|
||||
bool m_pending_items_fetched; // have we tried to fetch the item list already?
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
SBQueue::SBQueue () :
|
||||
m_opaque_sp (new QueueImpl())
|
||||
{
|
||||
}
|
||||
|
||||
SBQueue::SBQueue (const QueueSP& queue_sp) :
|
||||
m_opaque_sp (new QueueImpl (queue_sp))
|
||||
{
|
||||
}
|
||||
|
||||
SBQueue::SBQueue (const SBQueue &rhs)
|
||||
{
|
||||
if (&rhs == this)
|
||||
return;
|
||||
|
||||
m_opaque_sp = rhs.m_opaque_sp;
|
||||
}
|
||||
|
||||
const lldb::SBQueue &
|
||||
SBQueue::operator = (const lldb::SBQueue &rhs)
|
||||
{
|
||||
m_opaque_sp = rhs.m_opaque_sp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SBQueue::~SBQueue()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
SBQueue::IsValid() const
|
||||
{
|
||||
return m_opaque_sp->IsValid();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SBQueue::Clear ()
|
||||
{
|
||||
m_opaque_sp->Clear();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SBQueue::SetQueue (const QueueSP& queue_sp)
|
||||
{
|
||||
m_opaque_sp->SetQueue (queue_sp);
|
||||
}
|
||||
|
||||
lldb::queue_id_t
|
||||
SBQueue::GetQueueID () const
|
||||
{
|
||||
return m_opaque_sp->GetQueueID ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SBQueue::GetIndexID () const
|
||||
{
|
||||
return m_opaque_sp->GetIndexID ();
|
||||
}
|
||||
|
||||
const char *
|
||||
SBQueue::GetName () const
|
||||
{
|
||||
return m_opaque_sp->GetName ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SBQueue::GetNumThreads ()
|
||||
{
|
||||
return m_opaque_sp->GetNumThreads ();
|
||||
}
|
||||
|
||||
SBThread
|
||||
SBQueue::GetThreadAtIndex (uint32_t idx)
|
||||
{
|
||||
return m_opaque_sp->GetThreadAtIndex (idx);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
SBQueue::GetNumPendingItems ()
|
||||
{
|
||||
return m_opaque_sp->GetNumPendingItems ();
|
||||
}
|
||||
|
||||
SBQueueItem
|
||||
SBQueue::GetPendingItemAtIndex (uint32_t idx)
|
||||
{
|
||||
return m_opaque_sp->GetPendingItemAtIndex (idx);
|
||||
}
|
||||
|
||||
SBProcess
|
||||
SBQueue::GetProcess ()
|
||||
{
|
||||
return m_opaque_sp->GetProcess();
|
||||
}
|
120
source/API/SBQueueItem.cpp
Normal file
120
source/API/SBQueueItem.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//===-- SBQueueItem.cpp -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/lldb-python.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBQueueItem.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
#include "lldb/Core/Address.h"
|
||||
#include "lldb/Target/QueueItem.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Constructors
|
||||
//----------------------------------------------------------------------
|
||||
SBQueueItem::SBQueueItem () :
|
||||
m_queue_item_sp()
|
||||
{
|
||||
}
|
||||
|
||||
SBQueueItem::SBQueueItem (const QueueItemSP& queue_item_sp) :
|
||||
m_queue_item_sp (queue_item_sp)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------
|
||||
SBQueueItem::~SBQueueItem()
|
||||
{
|
||||
m_queue_item_sp.reset();
|
||||
}
|
||||
|
||||
bool
|
||||
SBQueueItem::IsValid() const
|
||||
{
|
||||
return m_queue_item_sp.get() != NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SBQueueItem::Clear ()
|
||||
{
|
||||
m_queue_item_sp.reset();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SBQueueItem::SetQueueItem (const QueueItemSP& queue_item_sp)
|
||||
{
|
||||
m_queue_item_sp = queue_item_sp;
|
||||
}
|
||||
|
||||
|
||||
lldb::QueueItemKind
|
||||
SBQueueItem::GetKind () const
|
||||
{
|
||||
QueueItemKind result = eQueueItemKindUnknown;
|
||||
if (m_queue_item_sp)
|
||||
{
|
||||
result = m_queue_item_sp->GetKind ();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
SBQueueItem::SetKind (lldb::QueueItemKind kind)
|
||||
{
|
||||
if (m_queue_item_sp)
|
||||
{
|
||||
m_queue_item_sp->SetKind (kind);
|
||||
}
|
||||
}
|
||||
|
||||
SBAddress
|
||||
SBQueueItem::GetAddress () const
|
||||
{
|
||||
SBAddress result;
|
||||
if (m_queue_item_sp)
|
||||
{
|
||||
result.SetAddress (&m_queue_item_sp->GetAddress());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
SBQueueItem::SetAddress (SBAddress addr)
|
||||
{
|
||||
if (m_queue_item_sp)
|
||||
{
|
||||
m_queue_item_sp->SetAddress (addr.ref());
|
||||
}
|
||||
}
|
||||
|
||||
SBThread
|
||||
SBQueueItem::GetExtendedBacktraceThread (const char *type)
|
||||
{
|
||||
SBThread result;
|
||||
if (m_queue_item_sp)
|
||||
{
|
||||
ThreadSP thread_sp;
|
||||
ConstString type_const (type);
|
||||
thread_sp = m_queue_item_sp->GetExtendedBacktraceThread (type_const);
|
||||
if (thread_sp)
|
||||
{
|
||||
result.SetThread (thread_sp);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
@ -52,6 +52,7 @@
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/LanguageRuntime.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/TargetList.h"
|
||||
|
||||
@ -688,57 +689,26 @@ SBTarget::Launch
|
||||
return sb_process;
|
||||
}
|
||||
}
|
||||
|
||||
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
|
||||
launch_flags |= eLaunchFlagDisableSTDIO;
|
||||
|
||||
ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);
|
||||
|
||||
Module *exe_module = target_sp->GetExecutableModulePointer();
|
||||
if (exe_module)
|
||||
launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
|
||||
if (argv)
|
||||
launch_info.GetArguments().AppendArguments (argv);
|
||||
if (envp)
|
||||
launch_info.GetEnvironmentEntries ().SetArguments (envp);
|
||||
|
||||
if (listener.IsValid())
|
||||
error.SetError (target_sp->Launch(listener.ref(), launch_info));
|
||||
else
|
||||
{
|
||||
if (listener.IsValid())
|
||||
process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL);
|
||||
else
|
||||
process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
|
||||
}
|
||||
error.SetError (target_sp->Launch(target_sp->GetDebugger().GetListener(), launch_info));
|
||||
|
||||
if (process_sp)
|
||||
{
|
||||
sb_process.SetSP (process_sp);
|
||||
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
|
||||
launch_flags |= eLaunchFlagDisableSTDIO;
|
||||
|
||||
ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);
|
||||
|
||||
Module *exe_module = target_sp->GetExecutableModulePointer();
|
||||
if (exe_module)
|
||||
launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
|
||||
if (argv)
|
||||
launch_info.GetArguments().AppendArguments (argv);
|
||||
if (envp)
|
||||
launch_info.GetEnvironmentEntries ().SetArguments (envp);
|
||||
|
||||
error.SetError (process_sp->Launch (launch_info));
|
||||
if (error.Success())
|
||||
{
|
||||
// We we are stopping at the entry point, we can return now!
|
||||
if (stop_at_entry)
|
||||
return sb_process;
|
||||
|
||||
// Make sure we are stopped at the entry
|
||||
StateType state = process_sp->WaitForProcessToStop (NULL);
|
||||
if (state == eStateStopped)
|
||||
{
|
||||
// resume the process to skip the entry point
|
||||
error.SetError (process_sp->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (target_sp->GetDebugger().GetAsyncExecution () == false)
|
||||
process_sp->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString ("unable to create lldb_private::Process");
|
||||
}
|
||||
sb_process.SetSP(target_sp->GetProcessSP());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -749,7 +719,7 @@ SBTarget::Launch
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
|
||||
target_sp.get(), process_sp.get());
|
||||
target_sp.get(), sb_process.GetSP().get());
|
||||
}
|
||||
|
||||
return sb_process;
|
||||
@ -761,7 +731,6 @@ SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
SBProcess sb_process;
|
||||
ProcessSP process_sp;
|
||||
TargetSP target_sp(GetSP());
|
||||
|
||||
if (log)
|
||||
@ -773,7 +742,8 @@ SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
|
||||
{
|
||||
Mutex::Locker api_locker (target_sp->GetAPIMutex());
|
||||
StateType state = eStateInvalid;
|
||||
process_sp = target_sp->GetProcessSP();
|
||||
{
|
||||
ProcessSP process_sp = target_sp->GetProcessSP();
|
||||
if (process_sp)
|
||||
{
|
||||
state = process_sp->GetState();
|
||||
@ -787,58 +757,20 @@ SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
|
||||
return sb_process;
|
||||
}
|
||||
}
|
||||
|
||||
if (state != eStateConnected)
|
||||
process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
|
||||
|
||||
if (process_sp)
|
||||
{
|
||||
sb_process.SetSP (process_sp);
|
||||
lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref();
|
||||
|
||||
Module *exe_module = target_sp->GetExecutableModulePointer();
|
||||
if (exe_module)
|
||||
launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
|
||||
|
||||
const ArchSpec &arch_spec = target_sp->GetArchitecture();
|
||||
if (arch_spec.IsValid())
|
||||
launch_info.GetArchitecture () = arch_spec;
|
||||
|
||||
error.SetError (process_sp->Launch (launch_info));
|
||||
const bool synchronous_execution = target_sp->GetDebugger().GetAsyncExecution () == false;
|
||||
if (error.Success())
|
||||
{
|
||||
if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the initial
|
||||
// stop to happen, else, return and let the caller watch for
|
||||
// the stop
|
||||
if (synchronous_execution)
|
||||
process_sp->WaitForProcessToStop (NULL);
|
||||
// We we are stopping at the entry point, we can return now!
|
||||
return sb_process;
|
||||
}
|
||||
|
||||
// Make sure we are stopped at the entry
|
||||
StateType state = process_sp->WaitForProcessToStop (NULL);
|
||||
if (state == eStateStopped)
|
||||
{
|
||||
// resume the process to skip the entry point
|
||||
error.SetError (process_sp->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (synchronous_execution)
|
||||
process_sp->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString ("unable to create lldb_private::Process");
|
||||
}
|
||||
|
||||
lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref();
|
||||
|
||||
Module *exe_module = target_sp->GetExecutableModulePointer();
|
||||
if (exe_module)
|
||||
launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
|
||||
|
||||
const ArchSpec &arch_spec = target_sp->GetArchitecture();
|
||||
if (arch_spec.IsValid())
|
||||
launch_info.GetArchitecture () = arch_spec;
|
||||
|
||||
error.SetError (target_sp->Launch (target_sp->GetDebugger().GetListener(), launch_info));
|
||||
sb_process.SetSP(target_sp->GetProcessSP());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -848,8 +780,8 @@ SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
|
||||
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
|
||||
target_sp.get(), process_sp.get());
|
||||
log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
|
||||
target_sp.get(), sb_process.GetSP().get());
|
||||
}
|
||||
|
||||
return sb_process;
|
||||
@ -1263,7 +1195,7 @@ SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
|
||||
if (target_sp)
|
||||
{
|
||||
Mutex::Locker api_locker (target_sp->GetAPIMutex());
|
||||
if (target_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, addr))
|
||||
if (target_sp->ResolveLoadAddress (vm_addr, addr))
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
@ -1273,6 +1205,26 @@ SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
|
||||
lldb::SBAddress
|
||||
SBTarget::ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr)
|
||||
{
|
||||
lldb::SBAddress sb_addr;
|
||||
Address &addr = sb_addr.ref();
|
||||
TargetSP target_sp(GetSP());
|
||||
if (target_sp)
|
||||
{
|
||||
Mutex::Locker api_locker (target_sp->GetAPIMutex());
|
||||
if (target_sp->ResolveLoadAddress (vm_addr, addr))
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
// We have a load address that isn't in a section, just return an address
|
||||
// with the offset filled in (the address) and the section set to NULL
|
||||
addr.SetRawAddress(vm_addr);
|
||||
return sb_addr;
|
||||
}
|
||||
|
||||
SBSymbolContext
|
||||
SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr,
|
||||
uint32_t resolve_scope)
|
||||
@ -2479,10 +2431,14 @@ SBTarget::SetSectionLoadAddress (lldb::SBSection section,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr))
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
uint32_t stop_id = 0;
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
|
||||
if (target_sp->SetSectionLoadAddress (section_sp, section_base_addr))
|
||||
{
|
||||
// Flush info in the process (stack frames, etc)
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
if (process_sp)
|
||||
process_sp->Flush();
|
||||
}
|
||||
@ -2511,10 +2467,14 @@ SBTarget::ClearSectionLoadAddress (lldb::SBSection section)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP()))
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
uint32_t stop_id = 0;
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
|
||||
if (target_sp->SetSectionUnloaded (section.GetSP()))
|
||||
{
|
||||
// Flush info in the process (stack frames, etc)
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
if (process_sp)
|
||||
process_sp->Flush();
|
||||
}
|
||||
@ -2539,7 +2499,7 @@ SBTarget::SetModuleLoadAddress (lldb::SBModule module, int64_t slide_offset)
|
||||
if (module_sp)
|
||||
{
|
||||
bool changed = false;
|
||||
if (module_sp->SetLoadAddress (*target_sp, slide_offset, changed))
|
||||
if (module_sp->SetLoadAddress (*target_sp, slide_offset, true, changed))
|
||||
{
|
||||
// The load was successful, make sure that at least some sections
|
||||
// changed before we notify that our module was loaded.
|
||||
@ -2586,13 +2546,18 @@ SBTarget::ClearModuleLoadAddress (lldb::SBModule module)
|
||||
SectionList *section_list = objfile->GetSectionList();
|
||||
if (section_list)
|
||||
{
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
uint32_t stop_id = 0;
|
||||
if (process_sp)
|
||||
stop_id = process_sp->GetStopID();
|
||||
|
||||
bool changed = false;
|
||||
const size_t num_sections = section_list->GetSize();
|
||||
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
|
||||
{
|
||||
SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
|
||||
if (section_sp)
|
||||
changed |= target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp) > 0;
|
||||
changed |= target_sp->SetSectionUnloaded (section_sp) > 0;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
|
@ -185,6 +185,14 @@ SBType::GetReferenceType()
|
||||
return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType())));
|
||||
}
|
||||
|
||||
SBType
|
||||
SBType::GetTypedefedType()
|
||||
{
|
||||
if (!IsValid())
|
||||
return SBType();
|
||||
return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType())));
|
||||
}
|
||||
|
||||
SBType
|
||||
SBType::GetDereferencedType()
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ SBTypeCategory::GetNumFormats ()
|
||||
if (!IsValid())
|
||||
return 0;
|
||||
|
||||
return m_opaque_sp->GetValueNavigator()->GetCount() + m_opaque_sp->GetRegexValueNavigator()->GetCount();
|
||||
return m_opaque_sp->GetTypeFormatsContainer()->GetCount() + m_opaque_sp->GetRegexTypeFormatsContainer()->GetCount();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -95,7 +95,7 @@ SBTypeCategory::GetNumSummaries ()
|
||||
{
|
||||
if (!IsValid())
|
||||
return 0;
|
||||
return m_opaque_sp->GetSummaryNavigator()->GetCount() + m_opaque_sp->GetRegexSummaryNavigator()->GetCount();
|
||||
return m_opaque_sp->GetTypeSummariesContainer()->GetCount() + m_opaque_sp->GetRegexTypeSummariesContainer()->GetCount();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -103,7 +103,7 @@ SBTypeCategory::GetNumFilters ()
|
||||
{
|
||||
if (!IsValid())
|
||||
return 0;
|
||||
return m_opaque_sp->GetFilterNavigator()->GetCount() + m_opaque_sp->GetRegexFilterNavigator()->GetCount();
|
||||
return m_opaque_sp->GetTypeFiltersContainer()->GetCount() + m_opaque_sp->GetRegexTypeFiltersContainer()->GetCount();
|
||||
}
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
@ -112,7 +112,7 @@ SBTypeCategory::GetNumSynthetics ()
|
||||
{
|
||||
if (!IsValid())
|
||||
return 0;
|
||||
return m_opaque_sp->GetSyntheticNavigator()->GetCount() + m_opaque_sp->GetRegexSyntheticNavigator()->GetCount();
|
||||
return m_opaque_sp->GetTypeSyntheticsContainer()->GetCount() + m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetCount();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -162,9 +162,9 @@ SBTypeCategory::GetFilterForType (SBTypeNameSpecifier spec)
|
||||
lldb::SyntheticChildrenSP children_sp;
|
||||
|
||||
if (spec.IsRegex())
|
||||
m_opaque_sp->GetRegexFilterNavigator()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
m_opaque_sp->GetRegexTypeFiltersContainer()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
else
|
||||
m_opaque_sp->GetFilterNavigator()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
m_opaque_sp->GetTypeFiltersContainer()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
|
||||
if (!children_sp)
|
||||
return lldb::SBTypeFilter();
|
||||
@ -186,9 +186,9 @@ SBTypeCategory::GetFormatForType (SBTypeNameSpecifier spec)
|
||||
lldb::TypeFormatImplSP format_sp;
|
||||
|
||||
if (spec.IsRegex())
|
||||
m_opaque_sp->GetRegexValueNavigator()->GetExact(ConstString(spec.GetName()), format_sp);
|
||||
m_opaque_sp->GetRegexTypeFormatsContainer()->GetExact(ConstString(spec.GetName()), format_sp);
|
||||
else
|
||||
m_opaque_sp->GetValueNavigator()->GetExact(ConstString(spec.GetName()), format_sp);
|
||||
m_opaque_sp->GetTypeFormatsContainer()->GetExact(ConstString(spec.GetName()), format_sp);
|
||||
|
||||
if (!format_sp)
|
||||
return lldb::SBTypeFormat();
|
||||
@ -209,9 +209,9 @@ SBTypeCategory::GetSummaryForType (SBTypeNameSpecifier spec)
|
||||
lldb::TypeSummaryImplSP summary_sp;
|
||||
|
||||
if (spec.IsRegex())
|
||||
m_opaque_sp->GetRegexSummaryNavigator()->GetExact(ConstString(spec.GetName()), summary_sp);
|
||||
m_opaque_sp->GetRegexTypeSummariesContainer()->GetExact(ConstString(spec.GetName()), summary_sp);
|
||||
else
|
||||
m_opaque_sp->GetSummaryNavigator()->GetExact(ConstString(spec.GetName()), summary_sp);
|
||||
m_opaque_sp->GetTypeSummariesContainer()->GetExact(ConstString(spec.GetName()), summary_sp);
|
||||
|
||||
if (!summary_sp)
|
||||
return lldb::SBTypeSummary();
|
||||
@ -233,9 +233,9 @@ SBTypeCategory::GetSyntheticForType (SBTypeNameSpecifier spec)
|
||||
lldb::SyntheticChildrenSP children_sp;
|
||||
|
||||
if (spec.IsRegex())
|
||||
m_opaque_sp->GetRegexSyntheticNavigator()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
else
|
||||
m_opaque_sp->GetSyntheticNavigator()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
m_opaque_sp->GetTypeSyntheticsContainer()->GetExact(ConstString(spec.GetName()), children_sp);
|
||||
|
||||
if (!children_sp)
|
||||
return lldb::SBTypeSynthetic();
|
||||
@ -312,9 +312,9 @@ SBTypeCategory::AddTypeFormat (SBTypeNameSpecifier type_name,
|
||||
return false;
|
||||
|
||||
if (type_name.IsRegex())
|
||||
m_opaque_sp->GetRegexValueNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), format.GetSP());
|
||||
m_opaque_sp->GetRegexTypeFormatsContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), format.GetSP());
|
||||
else
|
||||
m_opaque_sp->GetValueNavigator()->Add(ConstString(type_name.GetName()), format.GetSP());
|
||||
m_opaque_sp->GetTypeFormatsContainer()->Add(ConstString(type_name.GetName()), format.GetSP());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -329,9 +329,9 @@ SBTypeCategory::DeleteTypeFormat (SBTypeNameSpecifier type_name)
|
||||
return false;
|
||||
|
||||
if (type_name.IsRegex())
|
||||
return m_opaque_sp->GetRegexValueNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetRegexTypeFormatsContainer()->Delete(ConstString(type_name.GetName()));
|
||||
else
|
||||
return m_opaque_sp->GetValueNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetTypeFormatsContainer()->Delete(ConstString(type_name.GetName()));
|
||||
}
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
@ -383,9 +383,9 @@ SBTypeCategory::AddTypeSummary (SBTypeNameSpecifier type_name,
|
||||
}
|
||||
|
||||
if (type_name.IsRegex())
|
||||
m_opaque_sp->GetRegexSummaryNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), summary.GetSP());
|
||||
m_opaque_sp->GetRegexTypeSummariesContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), summary.GetSP());
|
||||
else
|
||||
m_opaque_sp->GetSummaryNavigator()->Add(ConstString(type_name.GetName()), summary.GetSP());
|
||||
m_opaque_sp->GetTypeSummariesContainer()->Add(ConstString(type_name.GetName()), summary.GetSP());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -401,9 +401,9 @@ SBTypeCategory::DeleteTypeSummary (SBTypeNameSpecifier type_name)
|
||||
return false;
|
||||
|
||||
if (type_name.IsRegex())
|
||||
return m_opaque_sp->GetRegexSummaryNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetRegexTypeSummariesContainer()->Delete(ConstString(type_name.GetName()));
|
||||
else
|
||||
return m_opaque_sp->GetSummaryNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetTypeSummariesContainer()->Delete(ConstString(type_name.GetName()));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -420,9 +420,9 @@ SBTypeCategory::AddTypeFilter (SBTypeNameSpecifier type_name,
|
||||
return false;
|
||||
|
||||
if (type_name.IsRegex())
|
||||
m_opaque_sp->GetRegexFilterNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), filter.GetSP());
|
||||
m_opaque_sp->GetRegexTypeFiltersContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), filter.GetSP());
|
||||
else
|
||||
m_opaque_sp->GetFilterNavigator()->Add(ConstString(type_name.GetName()), filter.GetSP());
|
||||
m_opaque_sp->GetTypeFiltersContainer()->Add(ConstString(type_name.GetName()), filter.GetSP());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -437,9 +437,9 @@ SBTypeCategory::DeleteTypeFilter (SBTypeNameSpecifier type_name)
|
||||
return false;
|
||||
|
||||
if (type_name.IsRegex())
|
||||
return m_opaque_sp->GetRegexFilterNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetRegexTypeFiltersContainer()->Delete(ConstString(type_name.GetName()));
|
||||
else
|
||||
return m_opaque_sp->GetFilterNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetTypeFiltersContainer()->Delete(ConstString(type_name.GetName()));
|
||||
}
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
@ -491,9 +491,9 @@ SBTypeCategory::AddTypeSynthetic (SBTypeNameSpecifier type_name,
|
||||
}
|
||||
|
||||
if (type_name.IsRegex())
|
||||
m_opaque_sp->GetRegexSyntheticNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), synth.GetSP());
|
||||
m_opaque_sp->GetRegexTypeSyntheticsContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), synth.GetSP());
|
||||
else
|
||||
m_opaque_sp->GetSyntheticNavigator()->Add(ConstString(type_name.GetName()), synth.GetSP());
|
||||
m_opaque_sp->GetTypeSyntheticsContainer()->Add(ConstString(type_name.GetName()), synth.GetSP());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -508,9 +508,9 @@ SBTypeCategory::DeleteTypeSynthetic (SBTypeNameSpecifier type_name)
|
||||
return false;
|
||||
|
||||
if (type_name.IsRegex())
|
||||
return m_opaque_sp->GetRegexSyntheticNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetRegexTypeSyntheticsContainer()->Delete(ConstString(type_name.GetName()));
|
||||
else
|
||||
return m_opaque_sp->GetSyntheticNavigator()->Delete(ConstString(type_name.GetName()));
|
||||
return m_opaque_sp->GetTypeSyntheticsContainer()->Delete(ConstString(type_name.GetName()));
|
||||
}
|
||||
#endif // LLDB_DISABLE_PYTHON
|
||||
|
||||
|
@ -25,7 +25,13 @@ m_opaque_sp()
|
||||
|
||||
SBTypeFormat::SBTypeFormat (lldb::Format format,
|
||||
uint32_t options)
|
||||
: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl(format,options)))
|
||||
: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl_Format(format,options)))
|
||||
{
|
||||
}
|
||||
|
||||
SBTypeFormat::SBTypeFormat (const char* type,
|
||||
uint32_t options)
|
||||
: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(type ? type : ""),options)))
|
||||
{
|
||||
}
|
||||
|
||||
@ -47,11 +53,19 @@ SBTypeFormat::IsValid() const
|
||||
lldb::Format
|
||||
SBTypeFormat::GetFormat ()
|
||||
{
|
||||
if (IsValid())
|
||||
return m_opaque_sp->GetFormat();
|
||||
if (IsValid() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat)
|
||||
return ((TypeFormatImpl_Format*)m_opaque_sp.get())->GetFormat();
|
||||
return lldb::eFormatInvalid;
|
||||
}
|
||||
|
||||
const char*
|
||||
SBTypeFormat::GetTypeName ()
|
||||
{
|
||||
if (IsValid() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum)
|
||||
return ((TypeFormatImpl_EnumType*)m_opaque_sp.get())->GetTypeName().AsCString("");
|
||||
return "";
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SBTypeFormat::GetOptions()
|
||||
{
|
||||
@ -63,14 +77,21 @@ SBTypeFormat::GetOptions()
|
||||
void
|
||||
SBTypeFormat::SetFormat (lldb::Format fmt)
|
||||
{
|
||||
if (CopyOnWrite_Impl())
|
||||
m_opaque_sp->SetFormat(fmt);
|
||||
if (CopyOnWrite_Impl(Type::eTypeFormat))
|
||||
((TypeFormatImpl_Format*)m_opaque_sp.get())->SetFormat(fmt);
|
||||
}
|
||||
|
||||
void
|
||||
SBTypeFormat::SetTypeName (const char* type)
|
||||
{
|
||||
if (CopyOnWrite_Impl(Type::eTypeEnum))
|
||||
((TypeFormatImpl_EnumType*)m_opaque_sp.get())->SetTypeName(ConstString(type ? type : ""));
|
||||
}
|
||||
|
||||
void
|
||||
SBTypeFormat::SetOptions (uint32_t value)
|
||||
{
|
||||
if (CopyOnWrite_Impl())
|
||||
if (CopyOnWrite_Impl(Type::eTypeKeepSame))
|
||||
m_opaque_sp->SetOptions(value);
|
||||
}
|
||||
|
||||
@ -143,13 +164,30 @@ SBTypeFormat::SBTypeFormat (const lldb::TypeFormatImplSP &typeformat_impl_sp) :
|
||||
}
|
||||
|
||||
bool
|
||||
SBTypeFormat::CopyOnWrite_Impl()
|
||||
SBTypeFormat::CopyOnWrite_Impl(Type type)
|
||||
{
|
||||
if (!IsValid())
|
||||
return false;
|
||||
if (m_opaque_sp.unique())
|
||||
|
||||
if (m_opaque_sp.unique() &&
|
||||
((type == Type::eTypeKeepSame) ||
|
||||
(type == Type::eTypeFormat && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat) ||
|
||||
(type == Type::eTypeEnum && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum))
|
||||
)
|
||||
return true;
|
||||
|
||||
SetSP(TypeFormatImplSP(new TypeFormatImpl(GetFormat(),GetOptions())));
|
||||
if (type == Type::eTypeKeepSame)
|
||||
{
|
||||
if (m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat)
|
||||
type = Type::eTypeFormat;
|
||||
else
|
||||
type = Type::eTypeEnum;
|
||||
}
|
||||
|
||||
if (type == Type::eTypeFormat)
|
||||
SetSP(TypeFormatImplSP(new TypeFormatImpl_Format(GetFormat(),GetOptions())));
|
||||
else
|
||||
SetSP(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(GetTypeName()),GetOptions())));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -96,7 +96,24 @@ class ValueImpl
|
||||
bool
|
||||
IsValid ()
|
||||
{
|
||||
return m_valobj_sp.get() != NULL;
|
||||
if (m_valobj_sp.get() == NULL)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
// FIXME: This check is necessary but not sufficient. We for sure don't want to touch SBValues whose owning
|
||||
// targets have gone away. This check is a little weak in that it enforces that restriction when you call
|
||||
// IsValid, but since IsValid doesn't lock the target, you have no guarantee that the SBValue won't go
|
||||
// invalid after you call this...
|
||||
// Also, an SBValue could depend on data from one of the modules in the target, and those could go away
|
||||
// independently of the target, for instance if a module is unloaded. But right now, neither SBValues
|
||||
// nor ValueObjects know which modules they depend on. So I have no good way to make that check without
|
||||
// tracking that in all the ValueObject subclasses.
|
||||
TargetSP target_sp = m_valobj_sp->GetTargetSP();
|
||||
if (target_sp && target_sp->IsValid())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
@ -120,6 +137,8 @@ class ValueImpl
|
||||
Target *target = value_sp->GetTargetSP().get();
|
||||
if (target)
|
||||
api_locker.Lock(target->GetAPIMutex());
|
||||
else
|
||||
return ValueObjectSP();
|
||||
|
||||
ProcessSP process_sp(value_sp->GetProcessSP());
|
||||
if (process_sp && !stop_locker.TryLock (&process_sp->GetRunLock()))
|
||||
@ -276,7 +295,7 @@ SBValue::IsValid ()
|
||||
// If this function ever changes to anything that does more than just
|
||||
// check if the opaque shared pointer is non NULL, then we need to update
|
||||
// all "if (m_opaque_sp)" code in this file.
|
||||
return m_opaque_sp.get() != NULL && m_opaque_sp->GetRootSP().get() != NULL;
|
||||
return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid() && m_opaque_sp->GetRootSP().get() != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -45,14 +45,19 @@ Breakpoint::GetEventIdentifier ()
|
||||
//----------------------------------------------------------------------
|
||||
// Breakpoint constructor
|
||||
//----------------------------------------------------------------------
|
||||
Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool hardware) :
|
||||
Breakpoint::Breakpoint(Target &target,
|
||||
SearchFilterSP &filter_sp,
|
||||
BreakpointResolverSP &resolver_sp,
|
||||
bool hardware,
|
||||
bool resolve_indirect_symbols) :
|
||||
m_being_created(true),
|
||||
m_hardware(hardware),
|
||||
m_target (target),
|
||||
m_filter_sp (filter_sp),
|
||||
m_resolver_sp (resolver_sp),
|
||||
m_options (),
|
||||
m_locations (*this)
|
||||
m_locations (*this),
|
||||
m_resolve_indirect_symbols(resolve_indirect_symbols)
|
||||
{
|
||||
m_being_created = false;
|
||||
}
|
||||
@ -87,7 +92,7 @@ Breakpoint::GetTarget () const
|
||||
BreakpointLocationSP
|
||||
Breakpoint::AddLocation (const Address &addr, bool *new_location)
|
||||
{
|
||||
return m_locations.AddLocation (addr, new_location);
|
||||
return m_locations.AddLocation (addr, m_resolve_indirect_symbols, new_location);
|
||||
}
|
||||
|
||||
BreakpointLocationSP
|
||||
|
@ -39,16 +39,29 @@ BreakpointLocation::BreakpointLocation
|
||||
Breakpoint &owner,
|
||||
const Address &addr,
|
||||
lldb::tid_t tid,
|
||||
bool hardware
|
||||
bool hardware,
|
||||
bool check_for_resolver
|
||||
) :
|
||||
StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
|
||||
m_being_created(true),
|
||||
m_should_resolve_indirect_functions (false),
|
||||
m_is_reexported (false),
|
||||
m_is_indirect (false),
|
||||
m_address (addr),
|
||||
m_owner (owner),
|
||||
m_options_ap (),
|
||||
m_bp_site_sp (),
|
||||
m_condition_mutex ()
|
||||
{
|
||||
if (check_for_resolver)
|
||||
{
|
||||
Symbol *symbol = m_address.CalculateSymbolContextSymbol();
|
||||
if (symbol && symbol->IsIndirect())
|
||||
{
|
||||
SetShouldResolveIndirectFunctions (true);
|
||||
}
|
||||
}
|
||||
|
||||
SetThreadID (tid);
|
||||
m_being_created = false;
|
||||
}
|
||||
@ -545,7 +558,10 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
||||
|
||||
if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
|
||||
{
|
||||
s->PutCString("where = ");
|
||||
if (IsReExported())
|
||||
s->PutCString ("re-exported target = ");
|
||||
else
|
||||
s->PutCString("where = ");
|
||||
sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
|
||||
}
|
||||
else
|
||||
@ -584,7 +600,10 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
||||
if (sc.symbol)
|
||||
{
|
||||
s->EOL();
|
||||
s->Indent("symbol = ");
|
||||
if (IsReExported())
|
||||
s->Indent ("re-exported target = ");
|
||||
else
|
||||
s->Indent("symbol = ");
|
||||
s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
|
||||
}
|
||||
}
|
||||
@ -612,6 +631,24 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
||||
m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
|
||||
else
|
||||
m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
|
||||
|
||||
if (IsIndirect() && m_bp_site_sp)
|
||||
{
|
||||
Address resolved_address;
|
||||
resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
|
||||
Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
|
||||
if (resolved_symbol)
|
||||
{
|
||||
if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
|
||||
s->Printf (", ");
|
||||
else if (level == lldb::eDescriptionLevelVerbose)
|
||||
{
|
||||
s->EOL();
|
||||
s->Indent();
|
||||
}
|
||||
s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
|
||||
}
|
||||
}
|
||||
|
||||
if (level == lldb::eDescriptionLevelVerbose)
|
||||
{
|
||||
|
@ -19,8 +19,10 @@
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
@ -39,12 +41,12 @@ BreakpointLocationList::~BreakpointLocationList()
|
||||
}
|
||||
|
||||
BreakpointLocationSP
|
||||
BreakpointLocationList::Create (const Address &addr)
|
||||
BreakpointLocationList::Create (const Address &addr, bool resolve_indirect_symbols)
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
// The location ID is just the size of the location list + 1
|
||||
lldb::break_id_t bp_loc_id = ++m_next_id;
|
||||
BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID, m_owner.IsHardware()));
|
||||
BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID, m_owner.IsHardware(), resolve_indirect_symbols));
|
||||
m_locations.push_back (bp_loc_sp);
|
||||
m_address_to_location[addr] = bp_loc_sp;
|
||||
return bp_loc_sp;
|
||||
@ -245,7 +247,7 @@ BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
||||
}
|
||||
|
||||
BreakpointLocationSP
|
||||
BreakpointLocationList::AddLocation (const Address &addr, bool *new_location)
|
||||
BreakpointLocationList::AddLocation (const Address &addr, bool resolve_indirect_symbols, bool *new_location)
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
|
||||
@ -254,7 +256,7 @@ BreakpointLocationList::AddLocation (const Address &addr, bool *new_location)
|
||||
BreakpointLocationSP bp_loc_sp (FindByAddress(addr));
|
||||
if (!bp_loc_sp)
|
||||
{
|
||||
bp_loc_sp = Create (addr);
|
||||
bp_loc_sp = Create (addr, resolve_indirect_symbols);
|
||||
if (bp_loc_sp)
|
||||
{
|
||||
bp_loc_sp->ResolveBreakpointSite();
|
||||
|
@ -272,6 +272,8 @@ BreakpointResolverName::SearchCallback
|
||||
{
|
||||
if (func_list.GetContextAtIndex(i, sc))
|
||||
{
|
||||
bool is_reexported = false;
|
||||
|
||||
if (sc.block && sc.block->GetInlinedFunctionInfo())
|
||||
{
|
||||
if (!sc.block->GetStartAddress(break_addr))
|
||||
@ -293,7 +295,10 @@ BreakpointResolverName::SearchCallback
|
||||
{
|
||||
const Symbol *actual_symbol = sc.symbol->ResolveReExportedSymbol(m_breakpoint->GetTarget());
|
||||
if (actual_symbol)
|
||||
{
|
||||
is_reexported = true;
|
||||
break_addr = actual_symbol->GetAddress();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -313,6 +318,7 @@ BreakpointResolverName::SearchCallback
|
||||
if (filter.AddressPasses(break_addr))
|
||||
{
|
||||
BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
|
||||
bp_loc_sp->SetIsReExported(is_reexported);
|
||||
if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
|
||||
{
|
||||
if (log)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user