Update LLDB snapshot to upstream r201577

Highlights include:

- Improvements to the remote GDB protocol client
  (r196610, r197579, r197857, r200072)

- Bug fixes for big-endian targets
  (r196808)

- Initial support for libdispatch (GCD) queues in the debuggee
  (r197190)

- Add "step-avoid-libraries" setting
  (r199943)

- IO subsystem improvements (including initial work on a curses gui)
  (r200263)

- Various bug fixes for memory leaks, LLDB segfaults, the C++ demangler,
  ELF core files, DWARF debug info, and others.

Sponsored by:	DARPA, AFRL
This commit is contained in:
Ed Maste 2014-02-18 19:52:51 +00:00
commit 12b93ac689
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/lldb-r201577/; revision=262187
256 changed files with 18806 additions and 9280 deletions

View File

@ -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"

View File

@ -118,6 +118,7 @@ class SBAddress
friend class SBTarget;
friend class SBThread;
friend class SBValue;
friend class SBQueueItem;
lldb_private::Address *
operator->();

View File

@ -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 &

View File

@ -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;

View File

@ -48,7 +48,6 @@ class SBFileSpecList;
class SBFrame;
class SBFunction;
class SBHostOS;
class SBInputReader;
class SBInstruction;
class SBInstructionList;
class SBLineEntry;

View File

@ -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;

View File

@ -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_

View File

@ -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);

View File

@ -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;

View 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_

View 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_

View File

@ -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);

View File

@ -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);

View File

@ -105,6 +105,9 @@ class SBType
lldb::SBType
GetReferenceType();
lldb::SBType
GetTypedefedType();
lldb::SBType
GetDereferencedType();

View File

@ -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);
};

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.
///

View File

@ -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

View File

@ -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 ();

View File

@ -175,6 +175,9 @@ class InstructionList
uint32_t
GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
uint32_t
GetIndexOfInstructionAtAddress (const Address &addr);
void
Clear();

View 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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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;
};
};

View File

@ -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);
//------------------------------------------------------------------

View File

@ -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
{

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;
//------------------------------------------------------------------

View File

@ -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);

View File

@ -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;
}

View File

@ -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_

View File

@ -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
};

View File

@ -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

View File

@ -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_

View File

@ -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);
};

View File

@ -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);
};

View File

@ -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

View File

@ -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.

View 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_

View File

@ -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

View File

@ -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.
//------------------------------------------------------------------

View File

@ -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);

View 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

View File

@ -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.

View File

@ -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;
};

View File

@ -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);
};

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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.

View 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)

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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.
//------------------------------------------------------------------

View File

@ -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.

View File

@ -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);
};

View File

@ -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);

View 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_

View 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_

View 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_

View 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 &section_sp);
bool
ResolveLoadAddress (uint32_t stop_id,
lldb::addr_t load_addr,
Address &so_addr);
bool
SetSectionLoadAddress (uint32_t stop_id,
const lldb::SectionSP &section_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 &section_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 &section_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_

View File

@ -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

View File

@ -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.

View File

@ -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 &section,
lldb::addr_t load_addr,
bool warn_multiple = false);
bool
SetSectionUnloaded (const lldb::SectionSP &section_sp);
bool
SetSectionUnloaded (const lldb::SectionSP &section_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,

View File

@ -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

View File

@ -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

View File

@ -73,7 +73,7 @@ class ThreadPlanStepInRange :
SetFlagsToDefault ();
bool
FrameMatchesAvoidRegexp ();
FrameMatchesAvoidCriteria ();
private:

View File

@ -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

View File

@ -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 &)>

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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 |\

View File

@ -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"

View File

@ -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)
{

View File

@ -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);
}
}

View File

@ -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
{

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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)
{

View 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();
}

View 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;
}

View File

@ -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)
{

View File

@ -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()
{

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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();

View File

@ -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