diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-26 19:24:53 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-26 19:24:53 +0000 |
commit | 5060b64b7d79491d507a75201be161fd0c38fcbb (patch) | |
tree | f4791d04b99ac52da01e646e5a6c9ce22ade61b9 | |
parent | d44a35e87e405ae98902dc491ba70ed82f58f592 (diff) | |
download | src-test2-5060b64b7d79491d507a75201be161fd0c38fcbb.tar.gz src-test2-5060b64b7d79491d507a75201be161fd0c38fcbb.zip |
Notes
50 files changed, 1423 insertions, 679 deletions
diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake index 60af9504ee8a..c40a24f056d8 100644 --- a/cmake/modules/LLDBConfig.cmake +++ b/cmake/modules/LLDBConfig.cmake @@ -250,12 +250,6 @@ endif() set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) -# If building on a 32-bit system, make sure off_t can store offsets > 2GB -if( CMAKE_SIZEOF_VOID_P EQUAL 4 ) - add_definitions( -D_LARGEFILE_SOURCE ) - add_definitions( -D_FILE_OFFSET_BITS=64 ) -endif() - if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite " "the makefiles distributed with LLDB. Please create a directory and run cmake " diff --git a/cmake/platforms/Android.cmake b/cmake/platforms/Android.cmake deleted file mode 100644 index 789322f4353c..000000000000 --- a/cmake/platforms/Android.cmake +++ /dev/null @@ -1,155 +0,0 @@ -# Toolchain config for Android standalone NDK. -# -# Usage: -# build host llvm and clang first -# cmake -DCMAKE_TOOLCHAIN_FILE=../lldb/cmake/platforms/Android.cmake \ -# -DANDROID_TOOLCHAIN_DIR=<toolchain_dir> \ -# -DANDROID_ABI=<target_abi> \ -# -DCMAKE_CXX_COMPILER_VERSION=<gcc_version> \ -# -DLLVM_TARGET_ARCH=<llvm_target_arch> \ -# -DLLVM_TARGETS_TO_BUILD=<llvm_targets_to_build> \ -# -DLLVM_TABLEGEN=<path_to_llvm-tblgen> \ -# -DCLANG_TABLEGEN=<path_to_clang-tblgen> -# -# Current Support: -# ANDROID_ABI = x86, x86_64 -# CMAKE_CXX_COMPILER_VERSION = 4.9 -# LLVM_TARGET_ARCH = X86 -# LLVM_TARGETS_TO_BUILD = X86 -# LLVM_TABLEGEN = path to host llvm-tblgen -# CLANG_TABLEGEN = path to host clang-tblgen - -if( DEFINED CMAKE_CROSSCOMPILING ) - return() -endif() - -get_property( IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE ) -if( IS_IN_TRY_COMPILE ) - # this seems necessary and works fine but I'm unsure if it breaks anything - return() -endif() - -set( CMAKE_SYSTEM_NAME Android ) -include( CMakeForceCompiler ) - -# flags and definitions -add_definitions( -DANDROID -DLLDB_DISABLE_LIBEDIT ) -set( ANDROID True ) -set( LLDB_DEFAULT_DISABLE_LIBEDIT True ) - -# linking lldb-server statically for Android avoids the need to ship two -# binaries (pie for API 21+ and non-pie for API 16-). It's possible to use -# a non-pie shim on API 16-, but that requires lldb-server to dynamically export -# its symbols, which significantly increases the binary size. Static linking, on -# the other hand, has little to no effect on the binary size. -if( NOT DEFINED LLVM_BUILD_STATIC ) - set( LLVM_BUILD_STATIC True CACHE INTERNAL "" FORCE ) - set( LLVM_ENABLE_PIC FALSE CACHE INTERNAL "" FORCE ) - set( BUILD_SHARED_LIBS FALSE CACHE INTERNAL "" FORCE ) -endif() - -set( ANDROID_ABI "${ANDROID_ABI}" CACHE INTERNAL "Android Abi" FORCE ) -if( ANDROID_ABI STREQUAL "x86" ) - set( CMAKE_SYSTEM_PROCESSOR "i686" ) - set( ANDROID_TOOLCHAIN_NAME "i686-linux-android" ) -elseif( ANDROID_ABI STREQUAL "x86_64" ) - set( CMAKE_SYSTEM_PROCESSOR "x86_64" ) - set( ANDROID_TOOLCHAIN_NAME "x86_64-linux-android" ) -elseif( ANDROID_ABI STREQUAL "armeabi" ) - set( CMAKE_SYSTEM_PROCESSOR "armv5te" ) - set( ANDROID_TOOLCHAIN_NAME "arm-linux-androideabi" ) -elseif( ANDROID_ABI STREQUAL "aarch64" ) - set( CMAKE_SYSTEM_PROCESSOR "aarch64" ) - set( ANDROID_TOOLCHAIN_NAME "aarch64-linux-android" ) -elseif( ANDROID_ABI STREQUAL "mips" ) - set( CMAKE_SYSTEM_PROCESSOR "mips" ) - set( ANDROID_TOOLCHAIN_NAME "mipsel-linux-android" ) -elseif( ANDROID_ABI STREQUAL "mips64" ) - set( CMAKE_SYSTEM_PROCESSOR "mips64" ) - set( ANDROID_TOOLCHAIN_NAME "mips64el-linux-android" ) -else() - message( SEND_ERROR "Unknown ANDROID_ABI = \"${ANDROID_ABI}\"." ) -endif() - -set( ANDROID_TOOLCHAIN_DIR "${ANDROID_TOOLCHAIN_DIR}" CACHE PATH "Android standalone toolchain directory" ) -set( ANDROID_SYSROOT "${ANDROID_TOOLCHAIN_DIR}/sysroot" CACHE PATH "Android Sysroot" ) - -# CMAKE_EXECUTABLE_SUFFIX is undefined in CMAKE_TOOLCHAIN_FILE -if( WIN32 ) - set( EXECUTABLE_SUFFIX ".exe" ) -endif() - -set( PYTHON_EXECUTABLE "${ANDROID_TOOLCHAIN_DIR}/bin/python${EXECUTABLE_SUFFIX}" CACHE PATH "Python exec path" ) - -if( NOT CMAKE_C_COMPILER ) - set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}" CACHE PATH "C compiler" ) - set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-g++${EXECUTABLE_SUFFIX}" CACHE PATH "C++ compiler" ) - set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}" CACHE PATH "assembler" ) - set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-strip${EXECUTABLE_SUFFIX}" CACHE PATH "strip" ) - set( CMAKE_AR "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ar${EXECUTABLE_SUFFIX}" CACHE PATH "archive" ) - set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ld${EXECUTABLE_SUFFIX}" CACHE PATH "linker" ) - set( CMAKE_NM "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-nm${EXECUTABLE_SUFFIX}" CACHE PATH "nm" ) - set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objcopy${EXECUTABLE_SUFFIX}" CACHE PATH "objcopy" ) - set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objdump${EXECUTABLE_SUFFIX}" CACHE PATH "objdump" ) - set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ranlib${EXECUTABLE_SUFFIX}" CACHE PATH "ranlib" ) -endif() - -set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT} -funwind-tables -fsigned-char -no-canonical-prefixes" ) -# TODO: different ARM abi have different flags such as neon, vfpv etc -if( X86 ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" ) -elseif( ANDROID_ABI STREQUAL "armeabi" ) - # 64 bit atomic operations used in c++ libraries require armv7-a instructions - # armv5te and armv6 were tried but do not work. - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mthumb" ) -elseif( ANDROID_ABI STREQUAL "mips" ) - # http://b.android.com/182094 - list( FIND LLDB_SYSTEM_LIBS atomic index ) - if( index EQUAL -1 ) - list( APPEND LLDB_SYSTEM_LIBS atomic ) - set( LLDB_SYSTEM_LIBS ${LLDB_SYSTEM_LIBS} CACHE INTERNAL "" FORCE ) - endif() -endif() - -# Use gold linker and enable safe ICF in case of x86, x86_64 and arm -if ( ANDROID_ABI STREQUAL "x86" OR - ANDROID_ABI STREQUAL "x86_64" OR - ANDROID_ABI STREQUAL "armeabi") - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold -Wl,--icf=safe" ) -endif() - -if( NOT LLVM_BUILD_STATIC ) - # PIE is required for API 21+ so we enable it if we're not statically linking - # unfortunately, it is not supported before API 16 so we need to do something - # else there see http://llvm.org/pr23457 - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -pie -fPIE" ) -endif() - -# linker flags -set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" ) -set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" ) - -# cache flags -set( CMAKE_CXX_FLAGS "" CACHE STRING "c++ flags" ) -set( CMAKE_C_FLAGS "" CACHE STRING "c flags" ) -set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "executable linker flags" ) -set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Android c/c++ flags" ) -set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Android c/c++ linker flags" ) - -# final flags -set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" ) -set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" ) -set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) - -# global includes and link directories -set( ANDROID_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_DIR}/include/c++/${ANDROID_COMPILER_VERSION}" ) -list( APPEND ANDROID_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_DIR}/include/python2.7" ) -include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_INCLUDE_DIRS} ) - -# target environment -set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_DIR}/bin" "${ANDROID_TOOLCHAIN_DIR}/${ANDROID_TOOLCHAIN_NAME}" "${ANDROID_SYSROOT}" ) - -# only search for libraries and includes in the ndk toolchain -set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) -set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) -set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) diff --git a/examples/python/disassembly_mode.py b/examples/python/disassembly_mode.py new file mode 100644 index 000000000000..19647cc6555e --- /dev/null +++ b/examples/python/disassembly_mode.py @@ -0,0 +1,48 @@ +""" Adds the 'toggle-disassembly' command to switch you into a disassembly only mode """ +import lldb + +class DisassemblyMode: + def __init__(self, debugger, unused): + self.dbg = debugger + self.interp = debugger.GetCommandInterpreter() + self.store_state() + self.mode_off = True + + def store_state(self): + self.dis_count = self.get_string_value("stop-disassembly-count") + self.dis_display = self.get_string_value("stop-disassembly-display") + self.before_count = self.get_string_value("stop-line-count-before") + self.after_count = self.get_string_value("stop-line-count-after") + + def get_string_value(self, setting): + result = lldb.SBCommandReturnObject() + self.interp.HandleCommand("settings show " + setting, result) + value = result.GetOutput().split(" = ")[1].rstrip("\n") + return value + + def set_value(self, setting, value): + result = lldb.SBCommandReturnObject() + self.interp.HandleCommand("settings set " + setting + " " + value, result) + + def __call__(self, debugger, command, exe_ctx, result): + if self.mode_off: + self.mode_off = False + self.store_state() + self.set_value("stop-disassembly-display","always") + self.set_value("stop-disassembly-count", "8") + self.set_value("stop-line-count-before", "0") + self.set_value("stop-line-count-after", "0") + result.AppendMessage("Disassembly mode on.") + else: + self.mode_off = True + self.set_value("stop-disassembly-display",self.dis_display) + self.set_value("stop-disassembly-count", self.dis_count) + self.set_value("stop-line-count-before", self.before_count) + self.set_value("stop-line-count-after", self.after_count) + result.AppendMessage("Disassembly mode off.") + + def get_short_help(self): + return "Toggles between a disassembly only mode and normal source mode\n" + +def __lldb_init_module(debugger, unused): + debugger.HandleCommand("command script add -c disassembly_mode.DisassemblyMode toggle-disassembly") diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h index d8604cd07114..cf61b10184d6 100644 --- a/include/lldb/API/LLDB.h +++ b/include/lldb/API/LLDB.h @@ -63,6 +63,8 @@ #include "lldb/API/SBThread.h" #include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBThreadPlan.h" +#include "lldb/API/SBTrace.h" +#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBType.h" #include "lldb/API/SBTypeCategory.h" #include "lldb/API/SBTypeEnumMember.h" diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h index 25443c4761af..d70e912d9200 100644 --- a/include/lldb/API/SBDefines.h +++ b/include/lldb/API/SBDefines.h @@ -79,6 +79,8 @@ class LLDB_API SBTarget; class LLDB_API SBThread; class LLDB_API SBThreadCollection; class LLDB_API SBThreadPlan; +class LLDB_API SBTrace; +class LLDB_API SBTraceOptions; class LLDB_API SBType; class LLDB_API SBTypeCategory; class LLDB_API SBTypeEnumMember; diff --git a/include/lldb/API/SBError.h b/include/lldb/API/SBError.h index 7f2f3a6cc5ec..a3b1f87053ad 100644 --- a/include/lldb/API/SBError.h +++ b/include/lldb/API/SBError.h @@ -61,6 +61,7 @@ protected: friend class SBProcess; friend class SBStructuredData; friend class SBThread; + friend class SBTrace; friend class SBTarget; friend class SBValue; friend class SBWatchpoint; diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h index fd95790c6686..0ee3a989d1b6 100644 --- a/include/lldb/API/SBProcess.h +++ b/include/lldb/API/SBProcess.h @@ -234,6 +234,33 @@ public: bool GetDescription(lldb::SBStream &description); + //------------------------------------------------------------------ + /// Start Tracing with the given SBTraceOptions. + /// + /// @param[in] options + /// Class containing trace options like trace buffer size, meta + /// data buffer size, TraceType and any custom parameters + /// {formatted as a JSON Dictionary}. In case of errors in + /// formatting, an error would be reported. + /// It must be noted that tracing options such as buffer sizes + /// or other custom parameters passed maybe invalid for some + /// trace technologies. In such cases the trace implementations + /// could choose to either throw an error or could round off to + /// the nearest valid options to start tracing if the passed + /// value is not supported. To obtain the actual used trace + /// options please use the GetTraceConfig API. For the custom + /// parameters, only the parameters recognized by the target + /// would be used and others would be ignored. + /// + /// @param[out] error + /// An error explaining what went wrong. + /// + /// @return + /// A SBTrace instance, which should be used + /// to get the trace data or other trace related operations. + //------------------------------------------------------------------ + lldb::SBTrace StartTrace(SBTraceOptions &options, lldb::SBError &error); + uint32_t GetNumSupportedHardwareWatchpoints(lldb::SBError &error) const; //------------------------------------------------------------------ diff --git a/include/lldb/API/SBStructuredData.h b/include/lldb/API/SBStructuredData.h index 9f0203bb245a..5fb5d3be65ad 100644 --- a/include/lldb/API/SBStructuredData.h +++ b/include/lldb/API/SBStructuredData.h @@ -13,8 +13,6 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" -class StructuredDataImpl; - namespace lldb { class SBStructuredData { @@ -31,14 +29,18 @@ public: bool IsValid() const; + lldb::SBError SetFromJSON(lldb::SBStream &stream); + void Clear(); lldb::SBError GetAsJSON(lldb::SBStream &stream) const; lldb::SBError GetDescription(lldb::SBStream &stream) const; -private: - std::unique_ptr<StructuredDataImpl> m_impl_up; +protected: + friend class SBTraceOptions; + + StructuredDataImplUP m_impl_up; }; } diff --git a/include/lldb/API/SBTrace.h b/include/lldb/API/SBTrace.h new file mode 100644 index 000000000000..e29a5db7cc46 --- /dev/null +++ b/include/lldb/API/SBTrace.h @@ -0,0 +1,122 @@ +//===-- SBTrace.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_SBTrace_h_ +#define LLDB_SBTrace_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBError.h" + +class TraceImpl; + +namespace lldb { + +class LLDB_API SBTrace { +public: + SBTrace(); + //------------------------------------------------------------------ + /// Obtain the trace data as raw bytes. + /// + /// @param[out] error + /// An error explaining what went wrong. + /// + /// @param[in] buf + /// Buffer to write the trace data to. + /// + /// @param[in] size + /// The size of the buffer used to read the data. This is + /// also the size of the data intended to read. It is also + /// possible to partially read the trace data for some trace + /// technologies by specifying a smaller buffer. + /// + /// @param[in] offset + /// The start offset to begin reading the trace data. + /// + /// @param[in] thread_id + /// Tracing could be started for the complete process or a + /// single thread, in the first case the uid obtained would + /// map to all the threads existing within the process and the + /// ones spawning later. The thread_id parameter can be used in + /// such a scenario to select the trace data for a specific + /// thread. + /// + /// @return + /// The size of the trace data effectively read by the API call. + //------------------------------------------------------------------ + size_t GetTraceData(SBError &error, void *buf, size_t size, size_t offset = 0, + lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + + //------------------------------------------------------------------ + /// Obtain any meta data as raw bytes for the tracing instance. + /// The input parameter definition is similar to the previous + /// function. + //------------------------------------------------------------------ + size_t GetMetaData(SBError &error, void *buf, size_t size, size_t offset = 0, + lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + + //------------------------------------------------------------------ + /// Stop the tracing instance. Stopping the trace will also + /// lead to deletion of any gathered trace data. + /// + /// @param[out] error + /// An error explaining what went wrong. + /// + /// @param[in] thread_id + /// The user id could map to a tracing instance for a thread + /// or could also map to a group of threads being traced with + /// the same trace options. A thread_id is normally optional + /// except in the case of tracing a complete process and tracing + /// needs to switched off on a particular thread. + /// A situation could occur where initially a thread (lets say + /// thread A) is being individually traced with a particular uid + /// and then tracing is started on the complete process, in this + /// case thread A will continue without any change. All newly + /// spawned threads would be traced with the uid of the process. + /// Now if the StopTrace API is called for the whole process, + /// thread A will not be stopped and must be stopped separately. + //------------------------------------------------------------------ + void StopTrace(SBError &error, + lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + + //------------------------------------------------------------------ + /// Get the trace configuration being used for the trace instance. + /// The threadid in the SBTraceOptions needs to be set when the + /// configuration used by a specific thread is being requested. + /// + /// @param[out] options + /// The trace options actually used by the trace instance + /// would be filled by the API. + /// + /// @param[out] error + /// An error explaining what went wrong. + //------------------------------------------------------------------ + void GetTraceConfig(SBTraceOptions &options, SBError &error); + + lldb::user_id_t GetTraceUID(); + + bool IsValid(); + +protected: + typedef std::shared_ptr<TraceImpl> TraceImplSP; + + friend class SBProcess; + + void SetTraceUID(lldb::user_id_t uid); + + TraceImplSP m_trace_impl_sp; + + lldb::ProcessSP GetSP() const; + + void SetSP(const ProcessSP &process_sp); + + lldb::ProcessWP m_opaque_wp; +}; +} // namespace lldb + +#endif // LLDB_SBTrace_h_ diff --git a/include/lldb/API/SBTraceOptions.h b/include/lldb/API/SBTraceOptions.h new file mode 100644 index 000000000000..c9735e1ca246 --- /dev/null +++ b/include/lldb/API/SBTraceOptions.h @@ -0,0 +1,58 @@ +//===-- SBTraceOptions ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef SBTRACEOPTIONS_H_ +#define SBTRACEOPTIONS_H_ + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class LLDB_API SBTraceOptions { +public: + SBTraceOptions(); + + lldb::TraceType getType() const; + + uint64_t getTraceBufferSize() const; + + /// The trace parameters consist of any custom parameters + /// apart from the generic parameters such as + /// TraceType, trace_buffer_size and meta_data_buffer_size. + /// The returned parameters would be formatted as a JSON Dictionary. + lldb::SBStructuredData getTraceParams(lldb::SBError &error); + + uint64_t getMetaDataBufferSize() const; + + /// SBStructuredData is meant to hold any custom parameters + /// apart from meta buffer size and trace size. They should + /// be formatted as a JSON Dictionary. + void setTraceParams(lldb::SBStructuredData ¶ms); + + void setType(lldb::TraceType type); + + void setTraceBufferSize(uint64_t size); + + void setMetaDataBufferSize(uint64_t size); + + void setThreadID(lldb::tid_t thread_id); + + lldb::tid_t getThreadID(); + + bool IsValid(); + +protected: + friend class SBProcess; + friend class SBTrace; + + lldb::TraceOptionsSP m_traceoptions_sp; +}; +} + +#endif /* SBTRACEOPTIONS_H_ */ diff --git a/include/lldb/Core/StructuredDataImpl.h b/include/lldb/Core/StructuredDataImpl.h new file mode 100644 index 000000000000..94f9cce52548 --- /dev/null +++ b/include/lldb/Core/StructuredDataImpl.h @@ -0,0 +1,95 @@ +//===-- StructuredDataImpl.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_StructuredDataImpl_h_ +#define liblldb_StructuredDataImpl_h_ + +#include "lldb/Core/Event.h" +#include "lldb/Core/StructuredData.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Target/StructuredDataPlugin.h" +#include "lldb/lldb-forward.h" + +#pragma mark-- +#pragma mark StructuredDataImpl + +namespace lldb_private { + +class StructuredDataImpl { +public: + StructuredDataImpl() : m_plugin_wp(), m_data_sp() {} + + StructuredDataImpl(const StructuredDataImpl &rhs) = default; + + StructuredDataImpl(const lldb::EventSP &event_sp) + : m_plugin_wp( + EventDataStructuredData::GetPluginFromEvent(event_sp.get())), + m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) { + } + + ~StructuredDataImpl() = default; + + StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default; + + bool IsValid() const { return m_data_sp.get() != nullptr; } + + void Clear() { + m_plugin_wp.reset(); + m_data_sp.reset(); + } + + Error GetAsJSON(Stream &stream) const { + Error error; + + if (!m_data_sp) { + error.SetErrorString("No structured data."); + return error; + } + + m_data_sp->Dump(stream); + return error; + } + + Error GetDescription(Stream &stream) const { + Error error; + + if (!m_data_sp) { + error.SetErrorString("Cannot pretty print structured data: " + "no data to print."); + return error; + } + + // Grab the plugin. + auto plugin_sp = lldb::StructuredDataPluginSP(m_plugin_wp); + if (!plugin_sp) { + error.SetErrorString("Cannot pretty print structured data: " + "plugin doesn't exist."); + return error; + } + + // Get the data's description. + return plugin_sp->GetDescription(m_data_sp, stream); + } + + StructuredData::ObjectSP GetObjectSP() { + return m_data_sp; + } + + void SetObjectSP(const StructuredData::ObjectSP &obj) { + m_data_sp = obj; + } + +private: + + lldb::StructuredDataPluginWP m_plugin_wp; + StructuredData::ObjectSP m_data_sp; +}; +} +#endif diff --git a/include/lldb/Core/TraceOptions.h b/include/lldb/Core/TraceOptions.h new file mode 100644 index 000000000000..ffa2bae7f659 --- /dev/null +++ b/include/lldb/Core/TraceOptions.h @@ -0,0 +1,62 @@ +//===-- TraceOptions.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_TraceOptions_h_ +#define liblldb_TraceOptions_h_ + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" + +#include "lldb/Core/StructuredData.h" + +namespace lldb_private { +class TraceOptions { +public: + TraceOptions() + : m_trace_params(new StructuredData::Dictionary()) {} + + const StructuredData::DictionarySP &getTraceParams() const { + return m_trace_params; + } + + lldb::TraceType getType() const { return m_type; } + + uint64_t getTraceBufferSize() const { return m_trace_buffer_size; } + + uint64_t getMetaDataBufferSize() const { return m_meta_data_buffer_size; } + + void setTraceParams(const StructuredData::DictionarySP &dict_obj) { + m_trace_params = dict_obj; + } + + void setType(lldb::TraceType type) { m_type = type; } + + void setTraceBufferSize(uint64_t size) { m_trace_buffer_size = size; } + + void setMetaDataBufferSize(uint64_t size) { m_meta_data_buffer_size = size; } + + void setThreadID(lldb::tid_t thread_id) { m_thread_id = thread_id; } + + lldb::tid_t getThreadID() { return m_thread_id; } + +private: + lldb::TraceType m_type; + uint64_t m_trace_buffer_size; + uint64_t m_meta_data_buffer_size; + lldb::tid_t m_thread_id; + + /// m_trace_params is meant to hold any custom parameters + /// apart from meta buffer size and trace size. + /// The interpretation of such parameters is left to + /// the lldb-server. + StructuredData::DictionarySP m_trace_params; +}; +} + +#endif // liblldb_TraceOptions_h_
\ No newline at end of file diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h index 1c923f317b7c..0898754b211a 100644 --- a/include/lldb/Core/ValueObject.h +++ b/include/lldb/Core/ValueObject.h @@ -27,6 +27,7 @@ #include "lldb/lldb-private-enumerations.h" // for AddressType #include "lldb/lldb-types.h" // for addr_t, offs... +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" // for StringRef @@ -37,7 +38,6 @@ #include <mutex> // for recursive_mutex #include <string> // for string #include <utility> // for pair -#include <vector> #include <stddef.h> // for size_t #include <stdint.h> // for uint32_t @@ -489,35 +489,19 @@ public: virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create); // this will always create the children if necessary - lldb::ValueObjectSP - GetChildAtIndexPath(const std::initializer_list<size_t> &idxs, - size_t *index_of_error = nullptr); - - lldb::ValueObjectSP GetChildAtIndexPath(const std::vector<size_t> &idxs, + lldb::ValueObjectSP GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs, size_t *index_of_error = nullptr); - lldb::ValueObjectSP GetChildAtIndexPath( - const std::initializer_list<std::pair<size_t, bool>> &idxs, - size_t *index_of_error = nullptr); - lldb::ValueObjectSP - GetChildAtIndexPath(const std::vector<std::pair<size_t, bool>> &idxs, + GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error = nullptr); // this will always create the children if necessary - lldb::ValueObjectSP - GetChildAtNamePath(const std::initializer_list<ConstString> &names, - ConstString *name_of_error = nullptr); - - lldb::ValueObjectSP GetChildAtNamePath(const std::vector<ConstString> &names, + lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef<ConstString> names, ConstString *name_of_error = nullptr); - lldb::ValueObjectSP GetChildAtNamePath( - const std::initializer_list<std::pair<ConstString, bool>> &names, - ConstString *name_of_error = nullptr); - lldb::ValueObjectSP - GetChildAtNamePath(const std::vector<std::pair<ConstString, bool>> &names, + GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString, bool>> names, ConstString *name_of_error = nullptr); virtual lldb::ValueObjectSP GetChildMemberWithName(const ConstString &name, diff --git a/include/lldb/Host/SocketAddress.h b/include/lldb/Host/SocketAddress.h index bc66ad915bbe..8e9026ba962c 100644 --- a/include/lldb/Host/SocketAddress.h +++ b/include/lldb/Host/SocketAddress.h @@ -41,8 +41,9 @@ public: //---------------------------------------------------------------------------- // Static method to get all address information for a host and/or service //---------------------------------------------------------------------------- - static std::vector<SocketAddress> GetAddressInfo(const char *hostname, - const char *servname); + static std::vector<SocketAddress> + GetAddressInfo(const char *hostname, const char *servname, int ai_family, + int ai_socktype, int ai_protocol, int ai_flags = 0); //------------------------------------------------------------------ // Constructors and Destructors diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index 56bbbfd53fdd..9a749efa7ae1 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -36,6 +36,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Core/StructuredData.h" #include "lldb/Core/ThreadSafeValue.h" +#include "lldb/Core/TraceOptions.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/ProcessRunLock.h" @@ -2766,6 +2767,79 @@ public: lldb::StructuredDataPluginSP GetStructuredDataPlugin(const ConstString &type_name) const; + //------------------------------------------------------------------ + /// Starts tracing with the configuration provided in options. To + /// enable tracing on the complete process the thread_id in the + /// options should be set to LLDB_INVALID_THREAD_ID. The API returns + /// a user_id which is needed by other API's that manipulate the + /// trace instance. + /// The handling of erroneous or unsupported configuration is left + /// to the trace technology implementations in the server, as they + /// could be returned as an error, or rounded to a valid + /// configuration to start tracing. In the later case the + /// GetTraceConfig should supply the actual used trace + /// configuration. + //------------------------------------------------------------------ + virtual lldb::user_id_t StartTrace(lldb::TraceOptionsSP &options, + Error &error) { + error.SetErrorString("Not implemented"); + return LLDB_INVALID_UID; + } + + //------------------------------------------------------------------ + /// Stops the tracing instance leading to deletion of the trace + /// data. The tracing instance is identified by the user_id which + /// is obtained when tracing was started from the StartTrace. + /// In case tracing of the complete process needs to be stopped + /// the thread_id should be set to LLDB_INVALID_THREAD_ID. + /// In the other case that tracing on an individual thread needs + /// to be stopped a thread_id can be supplied. + //------------------------------------------------------------------ + virtual void StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id, + Error &error) { + error.SetErrorString("Not implemented"); + } + + //------------------------------------------------------------------ + /// Provides the trace data as raw bytes. A buffer needs to be + /// supplied to copy the trace data. The exact behavior of this API + /// may vary across trace technology, as some may support partial + /// reading of the trace data from a specified offset while some + /// may not. The thread_id should be used to select a particular + /// thread for trace extraction. + //------------------------------------------------------------------ + virtual size_t GetData(lldb::user_id_t uid, lldb::tid_t thread_id, + Error &error, void *buf, size_t size, + size_t offset = 0) { + error.SetErrorString("Not implemented"); + return 0; + } + + //------------------------------------------------------------------ + /// Similar API as above except for obtaining meta data + //------------------------------------------------------------------ + virtual size_t GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id, + Error &error, void *buf, size_t size, + size_t offset = 0) { + error.SetErrorString("Not implemented"); + return 0; + } + + //------------------------------------------------------------------ + /// API to obtain the trace configuration used by a trace instance. + /// Configurations that may be specific to some trace technology + /// should be stored in the custom parameters. The options are + /// transported to the server, which shall interpret accordingly. + /// The thread_id can be specified in the options to obtain the + /// configuration used by a specific thread. The thread_id specified + /// should also match the uid otherwise an error will be returned. + //------------------------------------------------------------------ + virtual void GetTraceConfig(lldb::user_id_t uid, Error &error, + lldb::TraceOptionsSP &options) { + error.SetErrorString("Not implemented"); + return; + } + protected: void SetState(lldb::EventSP &event_sp); diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h index cf42828e2d5a..ad10bbba1a57 100644 --- a/include/lldb/lldb-enumerations.h +++ b/include/lldb/lldb-enumerations.h @@ -718,6 +718,13 @@ enum BasicType { eBasicTypeOther }; +enum TraceType { + eTraceTypeNone = 0, + + // Hardware Trace generated by the processor. + eTraceTypeProcessorTrace +}; + FLAGS_ENUM(TypeClass){ eTypeClassInvalid = (0u), eTypeClassArray = (1u << 0), eTypeClassBlockPointer = (1u << 1), eTypeClassBuiltin = (1u << 2), diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index 0970d691d802..2180b31527e0 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -215,6 +215,7 @@ class StreamFile; class StreamString; class StringList; struct StringSummaryFormat; +class StructuredDataImpl; class StructuredDataPlugin; class SystemRuntime; class TypeSummaryImpl; @@ -254,6 +255,7 @@ class ThreadPlanStepRange; class ThreadPlanStepThrough; class ThreadPlanTracer; class ThreadSpec; +class TraceOptions; class Type; class TypeAndOrName; class TypeCategoryMap; @@ -430,6 +432,7 @@ 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::unique_ptr<lldb_private::StructuredDataImpl> StructuredDataImplUP; typedef std::shared_ptr<lldb_private::StructuredDataPlugin> StructuredDataPluginSP; typedef std::weak_ptr<lldb_private::StructuredDataPlugin> @@ -451,6 +454,7 @@ typedef std::weak_ptr<lldb_private::Thread> ThreadWP; typedef std::shared_ptr<lldb_private::ThreadCollection> ThreadCollectionSP; typedef std::shared_ptr<lldb_private::ThreadPlan> ThreadPlanSP; typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP; +typedef std::shared_ptr<lldb_private::TraceOptions> TraceOptionsSP; typedef std::shared_ptr<lldb_private::Type> TypeSP; typedef std::weak_ptr<lldb_private::Type> TypeWP; typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP; diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py index 3998b9d8ab54..eafe62a0e08f 100644 --- a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py +++ b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py @@ -17,7 +17,7 @@ class NoreturnUnwind(TestBase): mydir = TestBase.compute_mydir(__file__) @skipIfWindows # clang-cl does not support gcc style attributes. - @expectedFailureAndroid(bugnumber="llvm.org/pr31192", archs=["x86_64"]) + @expectedFailureAndroid(bugnumber="llvm.org/pr31192") @expectedFailureAll(bugnumber="llvm.org/pr31192", oslist=['linux'], compiler="gcc", archs=['arm']) def test(self): """Test that we can backtrace correctly with 'noreturn' functions on the stack""" diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py index f1d7acfcc5ec..15657708ce46 100644 --- a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py +++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py @@ -89,7 +89,7 @@ class TestStepOverWatchpoint(TestBase): # resolve_location=True, read=False, write=True write_watchpoint = write_value.Watch(True, False, True, error) - self.assertTrue(read_watchpoint, "Failed to set write watchpoint.") + self.assertTrue(write_watchpoint, "Failed to set write watchpoint.") self.assertTrue(error.Success(), "Error while setting watchpoint: %s" % error.GetCString()) diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/main.c b/packages/Python/lldbsuite/test/lang/c/inlines/main.c index e9bd894bf726..f45e4e2b1497 100644 --- a/packages/Python/lldbsuite/test/lang/c/inlines/main.c +++ b/packages/Python/lldbsuite/test/lang/c/inlines/main.c @@ -5,6 +5,11 @@ inline void test2(int) __attribute__ ((always_inline)); void test2(int b) { printf("test2(%d)\n", b); //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"]) + { + int c = b * 2; + printf("c=%d\n", c); //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"]) + //% self.expect("expression c", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["84"]) + } } void test1(int a) { diff --git a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py index 0100a2727b38..d167f0a5591d 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py +++ b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py @@ -61,7 +61,7 @@ class StaticVariableTestCase(TestBase): bugnumber="Compiler emits incomplete debug info") @expectedFailureAll( compiler=["clang"], - compiler_version=["<", "3.8"], + compiler_version=["<", "3.9"], bugnumber='llvm.org/pr20550') @add_test_categories(['pyapi']) def test_with_python_api(self): diff --git a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile new file mode 100644 index 000000000000..aae93a20b9c8 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile @@ -0,0 +1,3 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules
\ No newline at end of file diff --git a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py new file mode 100644 index 000000000000..8e83a3ab1a4a --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py @@ -0,0 +1,7 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.expectedFailureAll( + oslist=["windows"], bugnumber="llvm.org/pr24764")])
\ No newline at end of file diff --git a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp new file mode 100644 index 000000000000..21ce8ca7080c --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp @@ -0,0 +1,36 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LIDENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace n { + struct D { + int i; + static int anInt() { return 2; } + int dump() { return i; } + }; + + class C { + public: + int foo(D *D); + }; +} + +using namespace n; + +int C::foo(D* D) { + return D->dump(); //% self.expect("expression -- D->dump()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"]) + //% self.expect("expression -- D::anInt()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"]) + +} + +int main (int argc, char const *argv[]) +{ + D myD { D::anInt() }; + C().foo(&myD); + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py b/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py index 878cc4fd4f76..fb7fadffa783 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py +++ b/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py @@ -111,8 +111,8 @@ class TestCppNsImport(TestBase): test_result = frame.EvaluateExpression("imported") self.assertTrue( - test_result.IsValid() and test_result.GetError().Fail(), - "imported is ambiguous") + test_result.IsValid() and test_result.GetValueAsSigned() == 99, + "imported = 99") test_result = frame.EvaluateExpression("single") self.assertTrue( diff --git a/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile b/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile new file mode 100644 index 000000000000..99bfa7e03b47 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile @@ -0,0 +1,3 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py b/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py new file mode 100644 index 000000000000..af362f5be5d7 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py @@ -0,0 +1,7 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.expectedFailureAll( + oslist=["windows"], bugnumber="llvm.org/pr24764")]) diff --git a/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp new file mode 100644 index 000000000000..292f9f64bcca --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp @@ -0,0 +1,40 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LIDENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +void *D = 0; + +class D { + static int i; +}; + +int D::i = 3; + +namespace errno { + int j = 4; +}; + +int twice(int n) +{ + return n * 2; //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"]) + //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["void"]) + //% self.expect("expression -- errno::j", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "4"]) +} + +const char getAChar() +{ + const char D[] = "Hello world"; + return D[0]; //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"]) + //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["char", "Hello"]) +} + +int main (int argc, char const *argv[]) +{ + int six = twice(3); + return 0; +} diff --git a/scripts/interface/SBProcess.i b/scripts/interface/SBProcess.i index b5e12a086fe4..527442e274ec 100644 --- a/scripts/interface/SBProcess.i +++ b/scripts/interface/SBProcess.i @@ -408,6 +408,9 @@ public: lldb::SBError SaveCore(const char *file_name); + lldb::SBTrace + StartTrace(SBTraceOptions &options, lldb::SBError &error); + lldb::SBError GetMemoryRegionInfo(lldb::addr_t load_addr, lldb::SBMemoryRegionInfo ®ion_info); diff --git a/scripts/interface/SBStructuredData.i b/scripts/interface/SBStructuredData.i index 225b088c4337..1c55bacd31be 100644 --- a/scripts/interface/SBStructuredData.i +++ b/scripts/interface/SBStructuredData.i @@ -38,5 +38,8 @@ namespace lldb { lldb::SBError GetDescription(lldb::SBStream &stream) const; + + lldb::SBError + SetFromJSON(lldb::SBStream &stream); }; } diff --git a/scripts/interface/SBTrace.i b/scripts/interface/SBTrace.i new file mode 100644 index 000000000000..799fd717c21d --- /dev/null +++ b/scripts/interface/SBTrace.i @@ -0,0 +1,34 @@ +//===-- SWIG Interface for SBTrace.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class LLDB_API SBTrace { +public: + SBTrace(); + size_t GetTraceData(SBError &error, void *buf, + size_t size, size_t offset, + lldb::tid_t thread_id); + + size_t GetMetaData(SBError &error, void *buf, + size_t size, size_t offset, + lldb::tid_t thread_id); + + void StopTrace(SBError &error, + lldb::tid_t thread_id); + + void GetTraceConfig(SBTraceOptions &options, + SBError &error); + + lldb::user_id_t GetTraceUID(); + + bool IsValid(); + +}; +} // namespace lldb
\ No newline at end of file diff --git a/scripts/interface/SBTraceOptions.i b/scripts/interface/SBTraceOptions.i new file mode 100644 index 000000000000..2fe6590842e3 --- /dev/null +++ b/scripts/interface/SBTraceOptions.i @@ -0,0 +1,38 @@ +//===-- SWIG Interface for SBTraceOptions -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class LLDB_API SBTraceOptions { +public: + SBTraceOptions(); + + lldb::TraceType getType() const; + + uint64_t getTraceBufferSize() const; + + lldb::SBStructuredData getTraceParams(lldb::SBError &error); + + uint64_t getMetaDataBufferSize() const; + + void setTraceParams(lldb::SBStructuredData ¶ms); + + void setType(lldb::TraceType type); + + void setTraceBufferSize(uint64_t size); + + void setMetaDataBufferSize(uint64_t size); + + void setThreadID(lldb::tid_t thread_id); + + lldb::tid_t getThreadID(); + + bool IsValid(); +}; +} diff --git a/scripts/lldb.swig b/scripts/lldb.swig index e81fabb19fb8..b0325e611d70 100644 --- a/scripts/lldb.swig +++ b/scripts/lldb.swig @@ -103,6 +103,8 @@ import six #include "lldb/API/SBThread.h" #include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBThreadPlan.h" +#include "lldb/API/SBTrace.h" +#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBType.h" #include "lldb/API/SBTypeCategory.h" #include "lldb/API/SBTypeEnumMember.h" @@ -186,6 +188,8 @@ import six %include "./interface/SBThread.i" %include "./interface/SBThreadCollection.i" %include "./interface/SBThreadPlan.i" +%include "./interface/SBTrace.i" +%include "./interface/SBTraceOptions.i" %include "./interface/SBType.i" %include "./interface/SBTypeCategory.i" %include "./interface/SBTypeEnumMember.i" diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt index 3b852a3d7402..9dd21bcf2aaf 100644 --- a/source/API/CMakeLists.txt +++ b/source/API/CMakeLists.txt @@ -67,6 +67,8 @@ add_lldb_library(liblldb SHARED SBThread.cpp SBThreadCollection.cpp SBThreadPlan.cpp + SBTrace.cpp + SBTraceOptions.cpp SBType.cpp SBTypeCategory.cpp SBTypeEnumMember.cpp diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp index 4cb367a03ad6..5614cb468a69 100644 --- a/source/API/SBProcess.cpp +++ b/source/API/SBProcess.cpp @@ -44,6 +44,8 @@ #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBThread.h" #include "lldb/API/SBThreadCollection.h" +#include "lldb/API/SBTrace.h" +#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBUnixSignals.h" using namespace lldb; @@ -349,6 +351,26 @@ size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const { return bytes_read; } +lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options, + lldb::SBError &error) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + error.Clear(); + SBTrace trace_instance; + trace_instance.SetSP(process_sp); + lldb::user_id_t uid = LLDB_INVALID_UID; + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + + uid = process_sp->StartTrace(options.m_traceoptions_sp, error.ref()); + trace_instance.SetTraceUID(uid); + LLDB_LOG(log, "SBProcess::returned uid - %" PRIx64, uid); + } + return trace_instance; +} + void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const { if (out == NULL) return; diff --git a/source/API/SBStructuredData.cpp b/source/API/SBStructuredData.cpp index 6d4c862306f9..2fca56f2f223 100644 --- a/source/API/SBStructuredData.cpp +++ b/source/API/SBStructuredData.cpp @@ -12,6 +12,7 @@ #include "lldb/API/SBStream.h" #include "lldb/Core/Event.h" #include "lldb/Core/StructuredData.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Utility/Error.h" #include "lldb/Utility/Stream.h" @@ -20,70 +21,6 @@ using namespace lldb; using namespace lldb_private; #pragma mark-- -#pragma mark StructuredDataImpl - -class StructuredDataImpl { -public: - StructuredDataImpl() : m_plugin_wp(), m_data_sp() {} - - StructuredDataImpl(const StructuredDataImpl &rhs) = default; - - StructuredDataImpl(const EventSP &event_sp) - : m_plugin_wp( - EventDataStructuredData::GetPluginFromEvent(event_sp.get())), - m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) { - } - - ~StructuredDataImpl() = default; - - StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default; - - bool IsValid() const { return m_data_sp.get() != nullptr; } - - void Clear() { - m_plugin_wp.reset(); - m_data_sp.reset(); - } - - SBError GetAsJSON(lldb_private::Stream &stream) const { - SBError sb_error; - - if (!m_data_sp) { - sb_error.SetErrorString("No structured data."); - return sb_error; - } - - m_data_sp->Dump(stream); - return sb_error; - } - - Error GetDescription(lldb_private::Stream &stream) const { - Error error; - - if (!m_data_sp) { - error.SetErrorString("Cannot pretty print structured data: " - "no data to print."); - return error; - } - - // Grab the plugin. - auto plugin_sp = StructuredDataPluginSP(m_plugin_wp); - if (!plugin_sp) { - error.SetErrorString("Cannot pretty print structured data: " - "plugin doesn't exist."); - return error; - } - - // Get the data's description. - return plugin_sp->GetDescription(m_data_sp, stream); - } - -private: - StructuredDataPluginWP m_plugin_wp; - StructuredData::ObjectSP m_data_sp; -}; - -#pragma mark-- #pragma mark SBStructuredData SBStructuredData::SBStructuredData() : m_impl_up(new StructuredDataImpl()) {} @@ -102,12 +39,26 @@ operator=(const lldb::SBStructuredData &rhs) { return *this; } +lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) { + lldb::SBError error; + std::string json_str(stream.GetData()); + + StructuredData::ObjectSP json_obj = StructuredData::ParseJSON(json_str); + m_impl_up->SetObjectSP(json_obj); + + if (!json_obj || json_obj->GetType() != StructuredData::Type::eTypeDictionary) + error.SetErrorString("Invalid Syntax"); + return error; +} + bool SBStructuredData::IsValid() const { return m_impl_up->IsValid(); } void SBStructuredData::Clear() { m_impl_up->Clear(); } SBError SBStructuredData::GetAsJSON(lldb::SBStream &stream) const { - return m_impl_up->GetAsJSON(stream.ref()); + SBError error; + error.SetError(m_impl_up->GetAsJSON(stream.ref())); + return error; } lldb::SBError SBStructuredData::GetDescription(lldb::SBStream &stream) const { diff --git a/source/API/SBTrace.cpp b/source/API/SBTrace.cpp new file mode 100644 index 000000000000..18f7d36e7759 --- /dev/null +++ b/source/API/SBTrace.cpp @@ -0,0 +1,109 @@ +//===-- SBTrace.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/Utility/Log.h" +#include "lldb/Target/Process.h" + +#include "lldb/API/SBTrace.h" +#include "lldb/API/SBTraceOptions.h" + +using namespace lldb; +using namespace lldb_private; + +class TraceImpl { +public: + lldb::user_id_t uid; +}; + +lldb::ProcessSP SBTrace::GetSP() const { return m_opaque_wp.lock(); } + +size_t SBTrace::GetTraceData(SBError &error, void *buf, size_t size, + size_t offset, lldb::tid_t thread_id) { + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + bytes_read = process_sp->GetData(GetTraceUID(), thread_id, error.ref(), buf, + size, offset); + LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read); + } + return bytes_read; +} + +size_t SBTrace::GetMetaData(SBError &error, void *buf, size_t size, + size_t offset, lldb::tid_t thread_id) { + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + + bytes_read = process_sp->GetMetaData(GetTraceUID(), thread_id, error.ref(), + buf, size, offset); + LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read); + } + return bytes_read; +} + +void SBTrace::StopTrace(SBError &error, lldb::tid_t thread_id) { + ProcessSP process_sp(GetSP()); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + return; + } + process_sp->StopTrace(GetTraceUID(), thread_id, error.ref()); +} + +void SBTrace::GetTraceConfig(SBTraceOptions &options, SBError &error) { + ProcessSP process_sp(GetSP()); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + process_sp->GetTraceConfig(GetTraceUID(), error.ref(), + options.m_traceoptions_sp); + } +} + +lldb::user_id_t SBTrace::GetTraceUID() { + if (m_trace_impl_sp) + return m_trace_impl_sp->uid; + return LLDB_INVALID_UID; +} + +void SBTrace::SetTraceUID(lldb::user_id_t uid) { + if (m_trace_impl_sp) + m_trace_impl_sp->uid = uid; +} + +SBTrace::SBTrace() { + m_trace_impl_sp.reset(new TraceImpl); + if (m_trace_impl_sp) + m_trace_impl_sp->uid = LLDB_INVALID_UID; +} + +void SBTrace::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; } + +bool SBTrace::IsValid() { + if (!m_trace_impl_sp) + return false; + if (!GetSP()) + return false; + return true; +} diff --git a/source/API/SBTraceOptions.cpp b/source/API/SBTraceOptions.cpp new file mode 100644 index 000000000000..474fa911f7ec --- /dev/null +++ b/source/API/SBTraceOptions.cpp @@ -0,0 +1,94 @@ +//===-- SBTraceOptions.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/API/SBTraceOptions.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/Utility/Log.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Core/TraceOptions.h" + +using namespace lldb; +using namespace lldb_private; + +SBTraceOptions::SBTraceOptions() { + m_traceoptions_sp.reset(new TraceOptions()); +} + +lldb::TraceType SBTraceOptions::getType() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getType(); + return lldb::TraceType::eTraceTypeNone; +} + +uint64_t SBTraceOptions::getTraceBufferSize() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getTraceBufferSize(); + return 0; +} + +lldb::SBStructuredData SBTraceOptions::getTraceParams(lldb::SBError &error) { + error.Clear(); + const lldb_private::StructuredData::DictionarySP dict_obj = + m_traceoptions_sp->getTraceParams(); + lldb::SBStructuredData structData; + if (dict_obj && structData.m_impl_up) + structData.m_impl_up->SetObjectSP(dict_obj->shared_from_this()); + else + error.SetErrorString("Empty trace params"); + return structData; +} + +uint64_t SBTraceOptions::getMetaDataBufferSize() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getTraceBufferSize(); + return 0; +} + +void SBTraceOptions::setTraceParams(lldb::SBStructuredData ¶ms) { + if (m_traceoptions_sp && params.m_impl_up) { + StructuredData::ObjectSP obj_sp = params.m_impl_up->GetObjectSP(); + if (obj_sp && obj_sp->GetAsDictionary() != nullptr) + m_traceoptions_sp->setTraceParams( + std::static_pointer_cast<StructuredData::Dictionary>(obj_sp)); + } + return; +} + +void SBTraceOptions::setType(lldb::TraceType type) { + if (m_traceoptions_sp) + m_traceoptions_sp->setType(type); +} + +void SBTraceOptions::setTraceBufferSize(uint64_t size) { + if (m_traceoptions_sp) + m_traceoptions_sp->setTraceBufferSize(size); +} + +void SBTraceOptions::setMetaDataBufferSize(uint64_t size) { + if (m_traceoptions_sp) + m_traceoptions_sp->setMetaDataBufferSize(size); +} + +bool SBTraceOptions::IsValid() { + if (m_traceoptions_sp) + return true; + return false; +} + +void SBTraceOptions::setThreadID(lldb::tid_t thread_id) { + if (m_traceoptions_sp) + m_traceoptions_sp->setThreadID(thread_id); +} + +lldb::tid_t SBTraceOptions::getThreadID() { + if (m_traceoptions_sp) + return m_traceoptions_sp->getThreadID(); + return LLDB_INVALID_THREAD_ID; +} diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp index 381763dab8e1..9e6b9da78b99 100644 --- a/source/Core/ValueObject.cpp +++ b/source/Core/ValueObject.cpp @@ -481,21 +481,8 @@ ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) { return child_sp; } -ValueObjectSP -ValueObject::GetChildAtIndexPath(const std::initializer_list<size_t> &idxs, - size_t *index_of_error) { - return GetChildAtIndexPath(std::vector<size_t>(idxs), index_of_error); -} - -ValueObjectSP ValueObject::GetChildAtIndexPath( - const std::initializer_list<std::pair<size_t, bool>> &idxs, - size_t *index_of_error) { - return GetChildAtIndexPath(std::vector<std::pair<size_t, bool>>(idxs), - index_of_error); -} - lldb::ValueObjectSP -ValueObject::GetChildAtIndexPath(const std::vector<size_t> &idxs, +ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs, size_t *index_of_error) { if (idxs.size() == 0) return GetSP(); @@ -512,7 +499,7 @@ ValueObject::GetChildAtIndexPath(const std::vector<size_t> &idxs, } lldb::ValueObjectSP ValueObject::GetChildAtIndexPath( - const std::vector<std::pair<size_t, bool>> &idxs, size_t *index_of_error) { + llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) { if (idxs.size() == 0) return GetSP(); ValueObjectSP root(GetSP()); @@ -528,20 +515,7 @@ lldb::ValueObjectSP ValueObject::GetChildAtIndexPath( } lldb::ValueObjectSP -ValueObject::GetChildAtNamePath(const std::initializer_list<ConstString> &names, - ConstString *name_of_error) { - return GetChildAtNamePath(std::vector<ConstString>(names), name_of_error); -} - -lldb::ValueObjectSP ValueObject::GetChildAtNamePath( - const std::initializer_list<std::pair<ConstString, bool>> &names, - ConstString *name_of_error) { - return GetChildAtNamePath(std::vector<std::pair<ConstString, bool>>(names), - name_of_error); -} - -lldb::ValueObjectSP -ValueObject::GetChildAtNamePath(const std::vector<ConstString> &names, +ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names, ConstString *name_of_error) { if (names.size() == 0) return GetSP(); @@ -558,7 +532,7 @@ ValueObject::GetChildAtNamePath(const std::vector<ConstString> &names, } lldb::ValueObjectSP ValueObject::GetChildAtNamePath( - const std::vector<std::pair<ConstString, bool>> &names, + llvm::ArrayRef<std::pair<ConstString, bool>> names, ConstString *name_of_error) { if (names.size() == 0) return GetSP(); diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp index 48c3ec1c48ed..b41cef6ca2eb 100644 --- a/source/Host/common/SocketAddress.cpp +++ b/source/Host/common/SocketAddress.cpp @@ -227,6 +227,18 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service, int ai_flags) { Clear(); + auto addresses = GetAddressInfo(host, service, ai_family, ai_socktype, ai_protocol, ai_flags); + if (!addresses.empty()) + *this = addresses[0]; + return IsValid(); +} + +std::vector<SocketAddress> +SocketAddress::GetAddressInfo(const char *hostname, const char *servname, + int ai_family, int ai_socktype, int ai_protocol, + int ai_flags) { + std::vector<SocketAddress> addr_list; + struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = ai_family; @@ -234,26 +246,8 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service, hints.ai_protocol = ai_protocol; hints.ai_flags = ai_flags; - bool result = false; - struct addrinfo *service_info_list = NULL; - int err = ::getaddrinfo(host, service, &hints, &service_info_list); - if (err == 0 && service_info_list) { - *this = service_info_list; - result = IsValid(); - } - - if (service_info_list) - ::freeaddrinfo(service_info_list); - - return result; -} - -std::vector<SocketAddress> SocketAddress::GetAddressInfo(const char *hostname, - const char *servname) { - std::vector<SocketAddress> addr_list; - struct addrinfo *service_info_list = NULL; - int err = ::getaddrinfo(hostname, servname, NULL, &service_info_list); + int err = ::getaddrinfo(hostname, servname, &hints, &service_info_list); if (err == 0 && service_info_list) { for (struct addrinfo *service_ptr = service_info_list; service_ptr != NULL; service_ptr = service_ptr->ai_next) { diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp index 9415b2bb3fd0..f1abb49055e5 100644 --- a/source/Host/freebsd/Host.cpp +++ b/source/Host/freebsd/Host.cpp @@ -55,49 +55,53 @@ using namespace lldb_private; static bool GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, ProcessInstanceInfo &process_info) { - if (process_info.ProcessIDIsValid()) { - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, - (int)process_info.GetProcessID()}; - - char arg_data[8192]; - size_t arg_data_size = sizeof(arg_data); - if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) { - DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), - sizeof(void *)); - lldb::offset_t offset = 0; - const char *cstr; - - cstr = data.GetCStr(&offset); - if (cstr) { - process_info.GetExecutableFile().SetFile(cstr, false); - - if (!(match_info_ptr == NULL || - NameMatches( - process_info.GetExecutableFile().GetFilename().GetCString(), - match_info_ptr->GetNameMatchType(), - match_info_ptr->GetProcessInfo().GetName()))) - return false; - - Args &proc_args = process_info.GetArguments(); - while (1) { - const uint8_t *p = data.PeekData(offset, 1); - while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { - ++offset; - p = data.PeekData(offset, 1); - } - if (p == NULL || offset >= arg_data_size) - return true; - - cstr = data.GetCStr(&offset); - if (cstr) - proc_args.AppendArgument(llvm::StringRef(cstr)); - else - return true; - } - } + if (!process_info.ProcessIDIsValid()) + return false; + + int pid = process_info.GetProcessID(); + + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, pid}; + + char arg_data[8192]; + size_t arg_data_size = sizeof(arg_data); + if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) != 0) + return false; + + DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), + sizeof(void *)); + lldb::offset_t offset = 0; + const char *cstr; + + cstr = data.GetCStr(&offset); + if (!cstr) + return false; + + process_info.GetExecutableFile().SetFile(cstr, false); + + if (!(match_info_ptr == NULL || + NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(), + match_info_ptr->GetNameMatchType(), + match_info_ptr->GetProcessInfo().GetName()))) + return false; + + Args &proc_args = process_info.GetArguments(); + while (1) { + const uint8_t *p = data.PeekData(offset, 1); + while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { + ++offset; + p = data.PeekData(offset, 1); } + if (p == NULL || offset >= arg_data_size) + break; + + cstr = data.GetCStr(&offset); + if (!cstr) + break; + + proc_args.AppendArgument(llvm::StringRef(cstr)); } - return false; + + return true; } static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) { @@ -113,26 +117,31 @@ static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) { static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { struct kinfo_proc proc_kinfo; size_t proc_kinfo_size; + const int pid = process_info.GetProcessID(); + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - if (process_info.ProcessIDIsValid()) { - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, - (int)process_info.GetProcessID()}; - proc_kinfo_size = sizeof(struct kinfo_proc); - - if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { - if (proc_kinfo_size > 0) { - process_info.SetParentProcessID(proc_kinfo.ki_ppid); - process_info.SetUserID(proc_kinfo.ki_ruid); - process_info.SetGroupID(proc_kinfo.ki_rgid); - process_info.SetEffectiveUserID(proc_kinfo.ki_uid); - if (proc_kinfo.ki_ngroups > 0) - process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]); - else - process_info.SetEffectiveGroupID(UINT32_MAX); - return true; - } - } - } + if (!process_info.ProcessIDIsValid()) + goto error; + + proc_kinfo_size = sizeof(struct kinfo_proc); + + if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) != 0) + goto error; + + if (proc_kinfo_size == 0) + goto error; + + process_info.SetParentProcessID(proc_kinfo.ki_ppid); + process_info.SetUserID(proc_kinfo.ki_ruid); + process_info.SetGroupID(proc_kinfo.ki_rgid); + process_info.SetEffectiveUserID(proc_kinfo.ki_uid); + if (proc_kinfo.ki_ngroups > 0) + process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]); + else + process_info.SetEffectiveGroupID(UINT32_MAX); + return true; + +error: process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID); process_info.SetUserID(UINT32_MAX); process_info.SetGroupID(UINT32_MAX); @@ -143,7 +152,11 @@ static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { + const ::pid_t our_pid = ::getpid(); + const ::uid_t our_uid = ::getuid(); std::vector<struct kinfo_proc> kinfos; + // Special case, if lldb is being run as root we can attach to anything. + bool all_users = match_info.GetMatchAllUsers() || (our_uid == 0); int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; @@ -163,29 +176,24 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); - bool all_users = match_info.GetMatchAllUsers(); - const ::pid_t our_pid = getpid(); - const uid_t our_uid = getuid(); for (size_t i = 0; i < actual_pid_count; i++) { const struct kinfo_proc &kinfo = kinfos[i]; - const bool kinfo_user_matches = (all_users || (kinfo.ki_ruid == our_uid) || - // Special case, if lldb is being run as - // root we can attach to anything. - (our_uid == 0)); - - if (kinfo_user_matches == false || // Make sure the user is acceptable - kinfo.ki_pid == our_pid || // Skip this process - kinfo.ki_pid == 0 || // Skip kernel (kernel pid is zero) - kinfo.ki_stat == SZOMB || // Zombies are bad, they like brains... - kinfo.ki_flag & P_TRACED || // Being debugged? - kinfo.ki_flag & P_WEXIT) // Working on exiting + + /* Make sure the user is acceptable */ + if (!all_users && kinfo.ki_ruid != our_uid) + continue; + + if (kinfo.ki_pid == our_pid || // Skip this process + kinfo.ki_pid == 0 || // Skip kernel (kernel pid is 0) + kinfo.ki_stat == SZOMB || // Zombies are bad + kinfo.ki_flag & P_TRACED || // Being debugged? + kinfo.ki_flag & P_WEXIT) // Working on exiting continue; // Every thread is a process in FreeBSD, but all the threads of a single - // process - // have the same pid. Do not store the process info in the result list if a - // process - // with given identifier is already registered there. + // process have the same pid. Do not store the process info in the + // result list if a process with given identifier is already registered + // there. bool already_registered = false; for (uint32_t pi = 0; !already_registered && (const int)kinfo.ki_numthreads > 1 && diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 70c77e9cde33..1f78fb96bc34 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -814,9 +814,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, current_id); } - - if (!context.m_found.variable && !context.m_found.local_vars_nsp) - ClangASTSource::FindExternalVisibleDecls(context); + + ClangASTSource::FindExternalVisibleDecls(context); } void ClangExpressionDeclMap::FindExternalVisibleDecls( @@ -1217,7 +1216,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } } - if (var) { + if (var && !variable_found) { variable_found = true; valobj = ValueObjectVariable::Create(frame, var); AddOneVariable(context, var, valobj, current_id); @@ -1248,303 +1247,297 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } } - if (!context.m_found.variable) { - const bool include_inlines = false; - const bool append = false; + const bool include_inlines = false; + const bool append = false; - if (namespace_decl && module_sp) { - const bool include_symbols = false; + if (namespace_decl && module_sp) { + const bool include_symbols = false; - module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase, - include_symbols, include_inlines, append, - sc_list); - } else if (target && !namespace_decl) { - const bool include_symbols = true; + module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase, + include_symbols, include_inlines, append, + sc_list); + } else if (target && !namespace_decl) { + const bool include_symbols = true; - // TODO Fix FindFunctions so that it doesn't return - // instance methods for eFunctionNameTypeBase. + // TODO Fix FindFunctions so that it doesn't return + // instance methods for eFunctionNameTypeBase. - target->GetImages().FindFunctions(name, eFunctionNameTypeFull, - include_symbols, include_inlines, - append, sc_list); - } + target->GetImages().FindFunctions(name, eFunctionNameTypeFull, + include_symbols, include_inlines, + append, sc_list); + } - // If we found more than one function, see if we can use the - // frame's decl context to remove functions that are shadowed - // by other functions which match in type but are nearer in scope. - // - // AddOneFunction will not add a function whose type has already been - // added, so if there's another function in the list with a matching - // type, check to see if their decl context is a parent of the current - // frame's or was imported via a and using statement, and pick the - // best match according to lookup rules. - if (sc_list.GetSize() > 1) { - // Collect some info about our frame's context. - StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); - SymbolContext frame_sym_ctx; - if (frame != nullptr) - frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | - lldb::eSymbolContextBlock); - CompilerDeclContext frame_decl_context = - frame_sym_ctx.block != nullptr - ? frame_sym_ctx.block->GetDeclContext() - : CompilerDeclContext(); - - // We can't do this without a compiler decl context for our frame. - if (frame_decl_context) { - clang::DeclContext *frame_decl_ctx = - (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext(); - ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>( - frame_decl_context.GetTypeSystem()); - - // Structure to hold the info needed when comparing function - // declarations. - struct FuncDeclInfo { - ConstString m_name; - CompilerType m_copied_type; - uint32_t m_decl_lvl; - SymbolContext m_sym_ctx; - }; - - // First, symplify things by looping through the symbol contexts - // to remove unwanted functions and separate out the functions we - // want to compare and prune into a separate list. - // Cache the info needed about the function declarations in a - // vector for efficiency. - SymbolContextList sc_sym_list; - uint32_t num_indices = sc_list.GetSize(); - std::vector<FuncDeclInfo> fdi_cache; - fdi_cache.reserve(num_indices); - for (uint32_t index = 0; index < num_indices; ++index) { - FuncDeclInfo fdi; - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); - - // We don't know enough about symbols to compare them, - // but we should keep them in the list. - Function *function = sym_ctx.function; - if (!function) { - sc_sym_list.Append(sym_ctx); - continue; - } - // Filter out functions without declaration contexts, as well as - // class/instance methods, since they'll be skipped in the - // code that follows anyway. - CompilerDeclContext func_decl_context = function->GetDeclContext(); - if (!func_decl_context || - func_decl_context.IsClassMethod(nullptr, nullptr, nullptr)) - continue; - // We can only prune functions for which we can copy the type. - CompilerType func_clang_type = - function->GetType()->GetFullCompilerType(); - CompilerType copied_func_type = GuardedCopyType(func_clang_type); - if (!copied_func_type) { - sc_sym_list.Append(sym_ctx); - continue; - } + // If we found more than one function, see if we can use the + // frame's decl context to remove functions that are shadowed + // by other functions which match in type but are nearer in scope. + // + // AddOneFunction will not add a function whose type has already been + // added, so if there's another function in the list with a matching + // type, check to see if their decl context is a parent of the current + // frame's or was imported via a and using statement, and pick the + // best match according to lookup rules. + if (sc_list.GetSize() > 1) { + // Collect some info about our frame's context. + StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); + SymbolContext frame_sym_ctx; + if (frame != nullptr) + frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | + lldb::eSymbolContextBlock); + CompilerDeclContext frame_decl_context = + frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext() + : CompilerDeclContext(); - fdi.m_sym_ctx = sym_ctx; - fdi.m_name = function->GetName(); - fdi.m_copied_type = copied_func_type; - fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL; - if (fdi.m_copied_type && func_decl_context) { - // Call CountDeclLevels to get the number of parent scopes we - // have to look through before we find the function declaration. - // When comparing functions of the same type, the one with a - // lower count will be closer to us in the lookup scope and - // shadows the other. - clang::DeclContext *func_decl_ctx = - (clang::DeclContext *) - func_decl_context.GetOpaqueDeclContext(); - fdi.m_decl_lvl = - ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx, - &fdi.m_name, &fdi.m_copied_type); - } - fdi_cache.emplace_back(fdi); - } + // We can't do this without a compiler decl context for our frame. + if (frame_decl_context) { + clang::DeclContext *frame_decl_ctx = + (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext(); + ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>( + frame_decl_context.GetTypeSystem()); - // Loop through the functions in our cache looking for matching types, - // then compare their scope levels to see which is closer. - std::multimap<CompilerType, const FuncDeclInfo *> matches; - for (const FuncDeclInfo &fdi : fdi_cache) { - const CompilerType t = fdi.m_copied_type; - auto q = matches.find(t); - if (q != matches.end()) { - if (q->second->m_decl_lvl > fdi.m_decl_lvl) - // This function is closer; remove the old set. - matches.erase(t); - else if (q->second->m_decl_lvl < fdi.m_decl_lvl) - // The functions in our set are closer - skip this one. - continue; - } - matches.insert(std::make_pair(t, &fdi)); + // Structure to hold the info needed when comparing function + // declarations. + struct FuncDeclInfo { + ConstString m_name; + CompilerType m_copied_type; + uint32_t m_decl_lvl; + SymbolContext m_sym_ctx; + }; + + // First, symplify things by looping through the symbol contexts + // to remove unwanted functions and separate out the functions we + // want to compare and prune into a separate list. + // Cache the info needed about the function declarations in a + // vector for efficiency. + SymbolContextList sc_sym_list; + uint32_t num_indices = sc_list.GetSize(); + std::vector<FuncDeclInfo> fdi_cache; + fdi_cache.reserve(num_indices); + for (uint32_t index = 0; index < num_indices; ++index) { + FuncDeclInfo fdi; + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(index, sym_ctx); + + // We don't know enough about symbols to compare them, + // but we should keep them in the list. + Function *function = sym_ctx.function; + if (!function) { + sc_sym_list.Append(sym_ctx); + continue; + } + // Filter out functions without declaration contexts, as well as + // class/instance methods, since they'll be skipped in the + // code that follows anyway. + CompilerDeclContext func_decl_context = function->GetDeclContext(); + if (!func_decl_context || + func_decl_context.IsClassMethod(nullptr, nullptr, nullptr)) + continue; + // We can only prune functions for which we can copy the type. + CompilerType func_clang_type = + function->GetType()->GetFullCompilerType(); + CompilerType copied_func_type = GuardedCopyType(func_clang_type); + if (!copied_func_type) { + sc_sym_list.Append(sym_ctx); + continue; } - // Loop through our matches and add their symbol contexts to our list. - SymbolContextList sc_func_list; - for (const auto &q : matches) - sc_func_list.Append(q.second->m_sym_ctx); + fdi.m_sym_ctx = sym_ctx; + fdi.m_name = function->GetName(); + fdi.m_copied_type = copied_func_type; + fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL; + if (fdi.m_copied_type && func_decl_context) { + // Call CountDeclLevels to get the number of parent scopes we + // have to look through before we find the function declaration. + // When comparing functions of the same type, the one with a + // lower count will be closer to us in the lookup scope and + // shadows the other. + clang::DeclContext *func_decl_ctx = + (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext(); + fdi.m_decl_lvl = ast->CountDeclLevels( + frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type); + } + fdi_cache.emplace_back(fdi); + } - // Rejoin the lists with the functions in front. - sc_list = sc_func_list; - sc_list.Append(sc_sym_list); + // Loop through the functions in our cache looking for matching types, + // then compare their scope levels to see which is closer. + std::multimap<CompilerType, const FuncDeclInfo *> matches; + for (const FuncDeclInfo &fdi : fdi_cache) { + const CompilerType t = fdi.m_copied_type; + auto q = matches.find(t); + if (q != matches.end()) { + if (q->second->m_decl_lvl > fdi.m_decl_lvl) + // This function is closer; remove the old set. + matches.erase(t); + else if (q->second->m_decl_lvl < fdi.m_decl_lvl) + // The functions in our set are closer - skip this one. + continue; + } + matches.insert(std::make_pair(t, &fdi)); } - } - if (sc_list.GetSize()) { - Symbol *extern_symbol = NULL; - Symbol *non_extern_symbol = NULL; + // Loop through our matches and add their symbol contexts to our list. + SymbolContextList sc_func_list; + for (const auto &q : matches) + sc_func_list.Append(q.second->m_sym_ctx); - for (uint32_t index = 0, num_indices = sc_list.GetSize(); - index < num_indices; ++index) { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); + // Rejoin the lists with the functions in front. + sc_list = sc_func_list; + sc_list.Append(sc_sym_list); + } + } - if (sym_ctx.function) { - CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext(); + if (sc_list.GetSize()) { + Symbol *extern_symbol = NULL; + Symbol *non_extern_symbol = NULL; - if (!decl_ctx) - continue; + for (uint32_t index = 0, num_indices = sc_list.GetSize(); + index < num_indices; ++index) { + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(index, sym_ctx); - // Filter out class/instance methods. - if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr)) - continue; + if (sym_ctx.function) { + CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext(); - AddOneFunction(context, sym_ctx.function, NULL, current_id); - context.m_found.function_with_type_info = true; - context.m_found.function = true; - } else if (sym_ctx.symbol) { - if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) { - sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target); - if (sym_ctx.symbol == NULL) - continue; - } + if (!decl_ctx) + continue; - if (sym_ctx.symbol->IsExternal()) - extern_symbol = sym_ctx.symbol; - else - non_extern_symbol = sym_ctx.symbol; + // Filter out class/instance methods. + if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr)) + continue; + + AddOneFunction(context, sym_ctx.function, NULL, current_id); + context.m_found.function_with_type_info = true; + context.m_found.function = true; + } else if (sym_ctx.symbol) { + if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) { + sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target); + if (sym_ctx.symbol == NULL) + continue; } + + if (sym_ctx.symbol->IsExternal()) + extern_symbol = sym_ctx.symbol; + else + non_extern_symbol = sym_ctx.symbol; } + } - if (!context.m_found.function_with_type_info) { - for (clang::NamedDecl *decl : decls_from_modules) { - if (llvm::isa<clang::FunctionDecl>(decl)) { - clang::NamedDecl *copied_decl = - llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl( - m_ast_context, &decl->getASTContext(), decl)); - if (copied_decl) { - context.AddNamedDecl(copied_decl); - context.m_found.function_with_type_info = true; - } + if (!context.m_found.function_with_type_info) { + for (clang::NamedDecl *decl : decls_from_modules) { + if (llvm::isa<clang::FunctionDecl>(decl)) { + clang::NamedDecl *copied_decl = + llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl( + m_ast_context, &decl->getASTContext(), decl)); + if (copied_decl) { + context.AddNamedDecl(copied_decl); + context.m_found.function_with_type_info = true; } } } + } - if (!context.m_found.function_with_type_info) { - if (extern_symbol) { - AddOneFunction(context, NULL, extern_symbol, current_id); - context.m_found.function = true; - } else if (non_extern_symbol) { - AddOneFunction(context, NULL, non_extern_symbol, current_id); - context.m_found.function = true; - } + if (!context.m_found.function_with_type_info) { + if (extern_symbol) { + AddOneFunction(context, NULL, extern_symbol, current_id); + context.m_found.function = true; + } else if (non_extern_symbol) { + AddOneFunction(context, NULL, non_extern_symbol, current_id); + context.m_found.function = true; } } + } - if (!context.m_found.function_with_type_info) { - // Try the modules next. + if (!context.m_found.function_with_type_info) { + // Try the modules next. - do { - if (ClangModulesDeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor()) { - bool append = false; - uint32_t max_matches = 1; - std::vector<clang::NamedDecl *> decls; + do { + if (ClangModulesDeclVendor *modules_decl_vendor = + m_target->GetClangModulesDeclVendor()) { + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; - if (!modules_decl_vendor->FindDecls(name, append, max_matches, - decls)) - break; + if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls)) + break; - clang::NamedDecl *const decl_from_modules = decls[0]; + clang::NamedDecl *const decl_from_modules = decls[0]; - if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) { - if (log) { - log->Printf(" CAS::FEVD[%u] Matching function found for " - "\"%s\" in the modules", - current_id, name.GetCString()); - } + if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) { + if (log) { + log->Printf(" CAS::FEVD[%u] Matching function found for " + "\"%s\" in the modules", + current_id, name.GetCString()); + } - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, &decl_from_modules->getASTContext(), - decl_from_modules); - clang::FunctionDecl *copied_function_decl = - copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) - : nullptr; + clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( + m_ast_context, &decl_from_modules->getASTContext(), + decl_from_modules); + clang::FunctionDecl *copied_function_decl = + copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) + : nullptr; - if (!copied_function_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a function " - "declaration from the modules", - current_id); + if (!copied_function_decl) { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a function " + "declaration from the modules", + current_id); - break; - } + break; + } - MaybeRegisterFunctionBody(copied_function_decl); + MaybeRegisterFunctionBody(copied_function_decl); - context.AddNamedDecl(copied_function_decl); + context.AddNamedDecl(copied_function_decl); - context.m_found.function_with_type_info = true; - context.m_found.function = true; - } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) { - if (log) { - log->Printf(" CAS::FEVD[%u] Matching variable found for " - "\"%s\" in the modules", - current_id, name.GetCString()); - } + context.m_found.function_with_type_info = true; + context.m_found.function = true; + } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) { + if (log) { + log->Printf(" CAS::FEVD[%u] Matching variable found for " + "\"%s\" in the modules", + current_id, name.GetCString()); + } - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, &decl_from_modules->getASTContext(), - decl_from_modules); - clang::VarDecl *copied_var_decl = - copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) - : nullptr; + clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( + m_ast_context, &decl_from_modules->getASTContext(), + decl_from_modules); + clang::VarDecl *copied_var_decl = + copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) + : nullptr; - if (!copied_var_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a variable " - "declaration from the modules", - current_id); + if (!copied_var_decl) { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a variable " + "declaration from the modules", + current_id); - break; - } + break; + } - context.AddNamedDecl(copied_var_decl); + context.AddNamedDecl(copied_var_decl); - context.m_found.variable = true; - } + context.m_found.variable = true; } - } while (0); - } - - if (target && !context.m_found.variable && !namespace_decl) { - // We couldn't find a non-symbol variable for this. Now we'll hunt for - // a generic - // data symbol, and -- if it is found -- treat it as a variable. - - const Symbol *data_symbol = FindGlobalDataSymbol(*target, name); - - if (data_symbol) { - std::string warning("got name from symbols: "); - warning.append(name.AsCString()); - const unsigned diag_id = - m_ast_context->getDiagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Level::Warning, "%0"); - m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str(); - AddOneGenericVariable(context, *data_symbol, current_id); - context.m_found.variable = true; } + } while (0); + } + + if (target && !context.m_found.variable && !namespace_decl) { + // We couldn't find a non-symbol variable for this. Now we'll hunt for + // a generic + // data symbol, and -- if it is found -- treat it as a variable. + + const Symbol *data_symbol = FindGlobalDataSymbol(*target, name); + + if (data_symbol) { + std::string warning("got name from symbols: "); + warning.append(name.AsCString()); + const unsigned diag_id = + m_ast_context->getDiagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Level::Warning, "%0"); + m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str(); + AddOneGenericVariable(context, *data_symbol, current_id); + context.m_found.variable = true; } } } diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp index cbc77ebe9987..562d988be837 100644 --- a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp +++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp @@ -588,7 +588,7 @@ addr_t ThreadSanitizerRuntime::GetFirstNonInternalFramePc( ModuleSP runtime_module_sp = GetRuntimeModuleSP(); StructuredData::Array *trace_array = trace->GetAsArray(); - for (int i = 0; i < trace_array->GetSize(); i++) { + for (size_t i = 0; i < trace_array->GetSize(); i++) { if (skip_one_frame && i == 0) continue; diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 72d99671612c..659a12b7eecf 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -395,7 +395,8 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (!D) return false; - ValueObjectSP layout_decider(D->GetChildAtIndexPath({0, 0})); + ValueObjectSP layout_decider( + D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0}))); // this child should exist if (!layout_decider) diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index e2902d5ef787..1d8b759d2fa8 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -3682,7 +3682,7 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { break; case DW_TAG_lexical_block: - decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die); + decl_ctx = GetDeclContextForBlock(die); try_parsing_type = false; break; @@ -3704,6 +3704,69 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { return nullptr; } +static bool IsSubroutine(const DWARFDIE &die) { + switch (die.Tag()) { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + return true; + default: + return false; + } +} + +static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) { + for (DWARFDIE candidate = die; candidate; candidate = candidate.GetParent()) { + if (IsSubroutine(candidate)) { + if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) { + return candidate; + } else { + return DWARFDIE(); + } + } + } + assert(!"Shouldn't call GetContainingFunctionWithAbstractOrigin on something " + "not in a function"); + return DWARFDIE(); +} + +static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) { + for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid(); + candidate = candidate.GetSibling()) { + if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) { + return candidate; + } + } + return DWARFDIE(); +} + +static DWARFDIE FindFirstChildWithAbstractOrigin(const DWARFDIE &block, + const DWARFDIE &function) { + assert(IsSubroutine(function)); + for (DWARFDIE context = block; context != function.GetParent(); + context = context.GetParent()) { + assert(!IsSubroutine(context) || context == function); + if (DWARFDIE child = FindAnyChildWithAbstractOrigin(context)) { + return child; + } + } + return DWARFDIE(); +} + +clang::DeclContext * +DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) { + assert(die.Tag() == DW_TAG_lexical_block); + DWARFDIE containing_function_with_abstract_origin = + GetContainingFunctionWithAbstractOrigin(die); + if (!containing_function_with_abstract_origin) { + return (clang::DeclContext *)ResolveBlockDIE(die); + } + DWARFDIE child = FindFirstChildWithAbstractOrigin( + die, containing_function_with_abstract_origin); + CompilerDeclContext decl_context = + GetDeclContextContainingUIDFromDWARF(child); + return (clang::DeclContext *)decl_context.GetOpaqueDeclContext(); +} + clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) { if (die && die.Tag() == DW_TAG_lexical_block) { clang::BlockDecl *decl = diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 3d6d08eef9ed..57c1fc07b2b6 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -66,6 +66,8 @@ protected: class DelayedAddObjCClassProperty; typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList; + clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die); + clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die); clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 856c371636d9..973b5ef9fb46 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3051,7 +3051,13 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) { case DW_TAG_lexical_block: case DW_TAG_subprogram: return die; - + case DW_TAG_inlined_subroutine: { + DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin); + if (abs_die) { + return abs_die; + } + break; + } default: break; } diff --git a/tools/debugserver/source/RNBRemote.cpp b/tools/debugserver/source/RNBRemote.cpp index 4c1f27eb1cb8..94260c619293 100644 --- a/tools/debugserver/source/RNBRemote.cpp +++ b/tools/debugserver/source/RNBRemote.cpp @@ -3614,7 +3614,7 @@ rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) { bool enable_compression = false; (void)enable_compression; -#if (defined (TARGET_OS_WATCH) && TARGET_OS_WATCHOS == 1) || (defined (TARGET_OS_IOS) && TARGET_OS_IOS == 1) || (defined (TARGET_OS_TVOS) && TARGET_OS_TVOS == 1) +#if (defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1) || (defined (TARGET_OS_IOS) && TARGET_OS_IOS == 1) || (defined (TARGET_OS_TV) && TARGET_OS_TV == 1) enable_compression = true; #endif diff --git a/unittests/Host/SocketAddressTest.cpp b/unittests/Host/SocketAddressTest.cpp index 3c18137ac063..17f9ccc19028 100644 --- a/unittests/Host/SocketAddressTest.cpp +++ b/unittests/Host/SocketAddressTest.cpp @@ -12,8 +12,21 @@ #include "lldb/Host/SocketAddress.h" namespace { -class SocketAddressTest : public ::testing::Test {}; -} +class SocketAddressTest : public testing::Test { +public: + static void SetUpTestCase() { +#ifdef _MSC_VER + WSADATA data; + ASSERT_EQ(0, WSAStartup(MAKEWORD(2, 2), &data)); +#endif + } + static void TearDownTestCase() { +#ifdef _MSC_VER + ASSERT_EQ(0, WSACleanup()); +#endif + } +}; +} // namespace using namespace lldb_private; @@ -34,6 +47,14 @@ TEST_F(SocketAddressTest, Set) { ASSERT_EQ(1139, sa.GetPort()); } +TEST_F(SocketAddressTest, GetAddressInfo) { + auto addr = SocketAddress::GetAddressInfo("127.0.0.1", nullptr, AF_UNSPEC, + SOCK_STREAM, IPPROTO_TCP); + ASSERT_EQ(1u, addr.size()); + EXPECT_EQ(AF_INET, addr[0].GetFamily()); + EXPECT_EQ("127.0.0.1", addr[0].GetIPAddress()); +} + #ifdef _WIN32 // we need to test our inet_ntop implementation for Windows XP diff --git a/www/build.html b/www/build.html index 5734bf9573aa..fbb35ae554ed 100755 --- a/www/build.html +++ b/www/build.html @@ -354,9 +354,8 @@ the target architecture. Since you already have a checkout of clang and lldb, you can compile a host version of clang in a separate folder and use that. Alternatively you can use system clang or even cross-gcc if your distribution - provides such packages (e.g., <code>g++-aarch64-linux-gnu</code> on Ubuntu). On - Android, a working toolchain can be produced by downloading the Android NDK and - running the contained <code>make-standalone-toolchain.sh</code> script. + provides such packages (e.g., <code>g++-aarch64-linux-gnu</code> + on Ubuntu). </p> <p> @@ -381,11 +380,6 @@ </p> <p> - In the case of Android, all required headers and libraries are provided by the - aforementioned <code>make-standalone-toolchain.sh</code> script. - </p> - - <p> Once all of the dependencies are in place, it's just a matter of configuring the build system with the locations and arguments of all the necessary tools. The most important cmake options here are: @@ -472,38 +466,37 @@ <h3>Example 2: Cross-compiling for Android on Linux</h3> <p> - All tools needed to build LLDB for android are available in the Android NDK. For - example, we can produce an x86 toolchain along with all the libraries and headers - by running + In the case of Android, the toolchain and all required headers and + libraries are available in the Android NDK. </p> - <code> - ./build/tools/make-standalone-toolchain.sh \<br/> - --platform=android-21 \<br/> - --toolchain=x86-4.9 \<br/> - --install-dir=$HOME/Toolchains/x86-android-toolchain - </code> + <p> - from inside the unzipped NDK. Toolchains for other architectures can be produced in - a similar manner. + The NDK also contains a cmake toolchain file, which makes + configuring the build much simpler. The compiler, include and + library paths will be configured by the toolchain file and all you + need to do is to select the architecture (ANDROID_ABI) and + platform level (ANDROID_PLATFORM, should be at least 21). You will + also need to set ANDROID_ALLOW_UNDEFINED_SYMBOLS=On, as the + toolchain file defaults to "no undefined symbols in shared + libraries", which is not compatible with some llvm libraries. The + first version of NDK which supports this approach is r14. </p> - <p> - For Android we provide a Android.cmake script which sets a lot of the required - options automatically. A cmake build can therefore be prepared with the following parameters: + For example, the following arguments are sufficient to configure + an android arm64 build: </p> <code> - -DCMAKE_TOOLCHAIN_FILE=cmake/platforms/Android.cmake \<br/> - -DANDROID_TOOLCHAIN_DIR=$HOME/Toolchains/x86-android-toolchain \<br/> - -DANDROID_ABI=x86 \<br/> - -DLLVM_HOST_TRIPLE=i386-unknown-linux-android \<br/> - -DLLVM_TABLEGEN=<path-to-host>/bin/llvm-tblgen \<br/> - -DCLANG_TABLEGEN=<path-to-host>/bin/clang-tblgen + -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \<br/> + -DANDROID_ABI=arm64-v8a \<br/> + -DANDROID_PLATFORM=android-21 \<br/> + -DANDROID_ALLOW_UNDEFINED_SYMBOLS=On \<br/> + -DLLVM_HOST_TRIPLE=aarch64-unknown-linux-android \<br/> + -DCROSS_TOOLCHAIN_FLAGS_NATIVE='-DCMAKE_C_COMPILER=cc;-DCMAKE_CXX_COMPILER=c++' <br/> </code> <p> - Note that the full LLVM build is not functional on android yet, so simply running - <code>ninja</code> will not work. You will need to manually specify the target you - want to build: <code>lldb</code>, <code>lldb-server</code>, etc. + Note that currently only lldb-server is functional on android. The + lldb client is not supported and unlikely to work. </p> </div> <div class="postfooter"></div> |