Index: tools/debugserver/source/CMakeLists.txt =================================================================== --- tools/debugserver/source/CMakeLists.txt +++ tools/debugserver/source/CMakeLists.txt @@ -2,12 +2,10 @@ include_directories(${LLDB_SOURCE_DIR}/source) include_directories(MacOSX/DarwinLog) -if (CMAKE_SYSTEM_NAME MATCHES "Darwin") - include_directories(MacOSX) - #include_directories(${CMAKE_CURRENT_BINARY_DIR}/MacOSX) +include_directories(MacOSX) +#include_directories(${CMAKE_CURRENT_BINARY_DIR}/MacOSX) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/../resources/lldb-debugserver-Info.plist") -endif() +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/../resources/lldb-debugserver-Info.plist") check_cxx_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" CXX_SUPPORTS_NO_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS) @@ -27,19 +25,31 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-extended-offsetof") endif () -if (NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") - add_definitions( - -DDEBUGSERVER_VERSION_STR="${LLDB_VERSION}" - ) -endif () +find_library(COCOA_LIBRARY Cocoa) +add_subdirectory(MacOSX) -if (CMAKE_SYSTEM_NAME MATCHES "Darwin") - find_library(COCOA_LIBRARY Cocoa) - add_subdirectory(MacOSX) -endif() +set(generated_mach_interfaces + ${CMAKE_CURRENT_BINARY_DIR}/mach_exc.h + ${CMAKE_CURRENT_BINARY_DIR}/mach_excServer.c + ${CMAKE_CURRENT_BINARY_DIR}/mach_excUser.c + ) +add_custom_command(OUTPUT ${generated_mach_interfaces} + COMMAND mig ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs + ) -add_lldb_library(lldbDebugserverCommon - debugserver.cpp +set(DEBUGSERVER_VERS_GENERATED_FILE ${CMAKE_CURRENT_BINARY_DIR}/debugserver_vers.c) +set_source_files_properties(${DEBUGSERVER_VERS_GENERATED_FILE} PROPERTIES GENERATED 1) + +add_custom_command(OUTPUT ${DEBUGSERVER_VERS_GENERATED_FILE} + COMMAND ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl + ${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj debugserver + > ${DEBUGSERVER_VERS_GENERATED_FILE} + DEPENDS ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl + ${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj + ) + +set(lldbDebugserverCommonSources DNBArch.cpp DNBBreakpoint.cpp DNB.cpp @@ -63,12 +73,54 @@ RNBSocket.cpp SysSignal.cpp TTYState.cpp + + MacOSX/CFBundle.cpp + MacOSX/CFString.cpp + MacOSX/Genealogy.cpp + MacOSX/MachException.cpp + MacOSX/MachProcess.mm + MacOSX/MachTask.mm + MacOSX/MachThread.cpp + MacOSX/MachThreadList.cpp + MacOSX/MachVMMemory.cpp + MacOSX/MachVMRegion.cpp + MacOSX/OsLogger.cpp + ${generated_mach_interfaces} + ${DEBUGSERVER_VERS_GENERATED_FILE}) + +add_library(lldbDebugserverCommon ${lldbDebugserverCommonSources}) + +target_link_libraries(lldbDebugserverCommon + INTERFACE ${COCOA_LIBRARY} + lldbDebugserverMacOSX_I386 + lldbDebugserverMacOSX_X86_64 + lldbDebugserverMacOSX_DarwinLog) + +set(LLVM_OPTIONAL_SOURCES ${lldbDebugserverCommonSources}) +add_lldb_tool(debugserver INCLUDE_IN_FRAMEWORK + debugserver.cpp LINK_LIBS - lldbHost - ${COCOA_LIBRARY} + lldbDebugserverCommon ) +set(LLDB_CODESIGN_IDENTITY "lldb_codesign" + CACHE STRING "Identity used for code signing. Set to empty string to skip the signing step.") +if (NOT ("${LLDB_CODESIGN_IDENTITY}" STREQUAL "")) + execute_process( + COMMAND xcrun -f codesign_allocate + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE CODESIGN_ALLOCATE + ) + add_custom_command(TARGET debugserver + POST_BUILD + # Note: --entitlements option removed (see comment above). + COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} + codesign --force --sign ${LLDB_CODESIGN_IDENTITY} + $ + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endif() Index: tools/debugserver/source/MacOSX/CMakeLists.txt =================================================================== --- tools/debugserver/source/MacOSX/CMakeLists.txt +++ tools/debugserver/source/MacOSX/CMakeLists.txt @@ -6,70 +6,3 @@ add_subdirectory(DarwinLog) include_directories(..) - -set(generated_mach_interfaces - ${CMAKE_CURRENT_BINARY_DIR}/mach_exc.h - ${CMAKE_CURRENT_BINARY_DIR}/mach_excServer.c - ${CMAKE_CURRENT_BINARY_DIR}/mach_excUser.c - ) -add_custom_command(OUTPUT ${generated_mach_interfaces} - COMMAND mig ${CMAKE_CURRENT_SOURCE_DIR}/dbgnub-mig.defs - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dbgnub-mig.defs - ) - -set(DEBUGSERVER_VERS_GENERATED_FILE ${CMAKE_CURRENT_BINARY_DIR}/debugserver_vers.c) -set_source_files_properties(${DEBUGSERVER_VERS_GENERATED_FILE} PROPERTIES GENERATED 1) - -add_custom_command(OUTPUT ${DEBUGSERVER_VERS_GENERATED_FILE} - COMMAND ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl - ${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj debugserver - > ${DEBUGSERVER_VERS_GENERATED_FILE} - DEPENDS ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl - ${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj - ) - -add_lldb_tool(debugserver INCLUDE_IN_FRAMEWORK - CFBundle.cpp - CFString.cpp - Genealogy.cpp - MachException.cpp - MachProcess.mm - MachTask.mm - MachThread.cpp - MachThreadList.cpp - MachVMMemory.cpp - MachVMRegion.cpp - OsLogger.cpp - ${generated_mach_interfaces} - ${DEBUGSERVER_VERS_GENERATED_FILE} - - LINK_LIBS - lldbDebugserverCommon - lldbDebugserverMacOSX_I386 - lldbDebugserverMacOSX_X86_64 - lldbDebugserverMacOSX_DarwinLog - ) - -set_source_files_properties( - HasAVX.s - # Necessary since compilation will fail with stand-alone assembler - PROPERTIES LANGUAGE C COMPILE_FLAGS "-x assembler-with-cpp" - ) - -set(LLDB_CODESIGN_IDENTITY "lldb_codesign" - CACHE STRING "Identity used for code signing. Set to empty string to skip the signing step.") -if (NOT ("${LLDB_CODESIGN_IDENTITY}" STREQUAL "")) - execute_process( - COMMAND xcrun -f codesign_allocate - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE CODESIGN_ALLOCATE - ) - add_custom_command(TARGET debugserver - POST_BUILD - # Note: --entitlements option removed (see comment above). - COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} - codesign --force --sign ${LLDB_CODESIGN_IDENTITY} - $ - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) -endif() Index: unittests/CMakeLists.txt =================================================================== --- unittests/CMakeLists.txt +++ unittests/CMakeLists.txt @@ -70,3 +70,7 @@ add_subdirectory(Target) add_subdirectory(UnwindAssembly) add_subdirectory(Utility) + +if(LLDB_CAN_USE_DEBUGSERVER) + add_subdirectory(debugserver) +endif() \ No newline at end of file Index: unittests/debugserver/CMakeLists.txt =================================================================== --- /dev/null +++ unittests/debugserver/CMakeLists.txt @@ -0,0 +1,19 @@ +# Note: debugserver is a Darwin-only implementation of a remote debugging +# server. It is not intended to be used on other platforms. The tests are here +# because using the LLDB Host API is convienent and allows testing of both parts +# of the debugserver communication path. If you are looking for a non-darwin +# remote debugging server, please use lldb-server. + +include_directories(${LLDB_SOURCE_DIR}/tools/debugserver/source + ${LLDB_SOURCE_DIR}/tools/debugserver/source/MacOSX) + +add_lldb_unittest(debugserverTests + RNBSocketTest.cpp + debugserver_LogCallback.cpp + + LINK_LIBS + lldbDebugserverCommon + lldbHost + LINK_COMPONENTS + Support + ) Index: unittests/debugserver/RNBSocketTest.cpp =================================================================== --- /dev/null +++ unittests/debugserver/RNBSocketTest.cpp @@ -0,0 +1,133 @@ +//===-- RNBSocketTest.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include +#include +#include + +#include "RNBDefs.h" +#include "RNBSocket.h" +#include "lldb/Host/Socket.h" +#include "lldb/Host/StringConvert.h" +#include "lldb/Host/common/TCPSocket.h" + +using namespace lldb_private; + +std::string hello = "Hello, world!"; +std::string goodbye = "Goodbye!"; + +static void ServerCallbackv4(const void *baton, in_port_t port) { + auto child_pid = fork(); + if (child_pid == 0) { + Socket *client_socket; + char addr_buffer[256]; + sprintf(addr_buffer, "%s:%d", baton, port); + Error err = Socket::TcpConnect(addr_buffer, false, client_socket); + if (err.Fail()) + abort(); + char buffer[32]; + size_t read_size = 32; + err = client_socket->Read((void *)&buffer[0], read_size); + if (err.Fail()) + abort(); + std::string Recv(&buffer[0], read_size); + if (Recv != hello) + abort(); + size_t write_size = goodbye.length(); + err = client_socket->Write(goodbye.c_str(), write_size); + if (err.Fail()) + abort(); + if (write_size != goodbye.length()) + abort(); + delete client_socket; + exit(0); + } +} + +void TestSocketListen(const char *addr) { + RNBSocket server_socket; + auto result = + server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr); + ASSERT_TRUE(result == rnb_success); + result = server_socket.Write(hello.c_str(), hello.length()); + ASSERT_TRUE(result == rnb_success); + std::string bye; + result = server_socket.Read(bye); + ASSERT_TRUE(result == rnb_success); + ASSERT_EQ(bye, goodbye); + + int exit_status; + wait(&exit_status); + ASSERT_EQ(exit_status, 0); +} + +TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); } + +void TestSocketConnect(const char *addr) { + char addr_wrap[256]; + sprintf(addr_wrap, "%s:0", addr); + + Socket *server_socket; + Predicate port_predicate; + port_predicate.SetValue(0, eBroadcastNever); + Error err = + Socket::TcpListen(addr_wrap, false, server_socket, &port_predicate); + ASSERT_FALSE(err.Fail()); + + auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber(); + auto child_pid = fork(); + if (child_pid != 0) { + RNBSocket client_socket; + auto result = client_socket.Connect(addr, port); + ASSERT_TRUE(result == rnb_success); + result = client_socket.Write(hello.c_str(), hello.length()); + ASSERT_TRUE(result == rnb_success); + std::string bye; + result = client_socket.Read(bye); + ASSERT_TRUE(result == rnb_success); + ASSERT_EQ(bye, goodbye); + } else { + Socket *connected_socket; + err = server_socket->Accept(connected_socket); + if (err.Fail()) { + llvm::errs() << err.AsCString(); + abort(); + } + char buffer[32]; + size_t read_size = 32; + err = connected_socket->Read((void *)&buffer[0], read_size); + if (err.Fail()) { + llvm::errs() << err.AsCString(); + abort(); + } + std::string Recv(&buffer[0], read_size); + if (Recv != hello) { + llvm::errs() << err.AsCString(); + abort(); + } + size_t write_size = goodbye.length(); + err = connected_socket->Write(goodbye.c_str(), write_size); + if (err.Fail()) { + llvm::errs() << err.AsCString(); + abort(); + } + if (write_size != goodbye.length()) { + llvm::errs() << err.AsCString(); + abort(); + } + exit(0); + } + int exit_status; + wait(&exit_status); + ASSERT_EQ(exit_status, 0); +} + +TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); } Index: unittests/debugserver/debugserver_LogCallback.cpp =================================================================== --- /dev/null +++ unittests/debugserver/debugserver_LogCallback.cpp @@ -0,0 +1,20 @@ +//===-- debugserver_LogCallback.cpp -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//------------------------------------------------------------------------------ +// this function is defined in debugserver.cpp, but is needed to link the +// debugserver Common library. It is for logging only, so it is left +// unimplemented here. +//------------------------------------------------------------------------------ + +#include +#include + +void FileLogCallback(void *baton, uint32_t flags, const char *format, + va_list args) {}