diff --git a/lldb/include/lldb/Core/Stream.h b/lldb/include/lldb/Core/Stream.h index 128765b3cfb9..1fc277b70a54 100644 --- a/lldb/include/lldb/Core/Stream.h +++ b/lldb/include/lldb/Core/Stream.h @@ -181,14 +181,15 @@ public: int PutBytesAsRawHex8 (const void *src, - size_t src_len, - lldb::ByteOrder src_byte_order, - lldb::ByteOrder dst_byte_order); + size_t src_len, + lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid, + lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid); int - PutRawBytes (const void *s, size_t src_len, - lldb::ByteOrder src_byte_order, - lldb::ByteOrder dst_byte_order); + PutRawBytes (const void *s, + size_t src_len, + lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid, + lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid); int PutCStringAsRawHex8 (const char *s); diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h index c05aa0bb3b03..6f43f173ee51 100644 --- a/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -87,7 +87,7 @@ public: SetImmediateErrorFile (FILE *fh, bool transfer_fh_ownership = false) { lldb::StreamSP stream_sp (new StreamFile (fh, transfer_fh_ownership)); - m_out_stream.SetStreamAtIndex (eImmediateStreamIndex, stream_sp); + m_err_stream.SetStreamAtIndex (eImmediateStreamIndex, stream_sp); } void @@ -99,7 +99,6 @@ public: void SetImmediateErrorStream (const lldb::StreamSP &stream_sp) { - // Ensure we always have our normal output stream m_err_stream.SetStreamAtIndex (eImmediateStreamIndex, stream_sp); } diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 1bb1b51bd3b5..dccdc6c7de67 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1928,6 +1928,12 @@ protected: void RestorePrivateProcessEvents (); + + bool + PrivateStateThreadIsValid () const + { + return m_private_state_thread != LLDB_INVALID_HOST_THREAD; + } //------------------------------------------------------------------ // Member variables diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 37e9b9c61054..31c4752c08a2 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -16,6 +16,16 @@ 2617447A11685869005ADD65 /* SBType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2617447911685869005ADD65 /* SBType.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2618D7921240116900F2B8FE /* SectionLoadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618D7911240116900F2B8FE /* SectionLoadList.cpp */; }; 2618D9EB12406FE600F2B8FE /* NameToDIE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618D9EA12406FE600F2B8FE /* NameToDIE.cpp */; }; + 2618EE651315B29C001D6D71 /* GDBRemoteCommunication.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE5B1315B29C001D6D71 /* GDBRemoteCommunication.cpp */; }; + 2618EE661315B29C001D6D71 /* GDBRemoteCommunication.h in Headers */ = {isa = PBXBuildFile; fileRef = 2618EE5C1315B29C001D6D71 /* GDBRemoteCommunication.h */; }; + 2618EE671315B29C001D6D71 /* GDBRemoteRegisterContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE5D1315B29C001D6D71 /* GDBRemoteRegisterContext.cpp */; }; + 2618EE681315B29C001D6D71 /* GDBRemoteRegisterContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 2618EE5E1315B29C001D6D71 /* GDBRemoteRegisterContext.h */; }; + 2618EE691315B29C001D6D71 /* ProcessGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE5F1315B29C001D6D71 /* ProcessGDBRemote.cpp */; }; + 2618EE6A1315B29C001D6D71 /* ProcessGDBRemote.h in Headers */ = {isa = PBXBuildFile; fileRef = 2618EE601315B29C001D6D71 /* ProcessGDBRemote.h */; }; + 2618EE6B1315B29C001D6D71 /* ProcessGDBRemoteLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE611315B29C001D6D71 /* ProcessGDBRemoteLog.cpp */; }; + 2618EE6C1315B29C001D6D71 /* ProcessGDBRemoteLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 2618EE621315B29C001D6D71 /* ProcessGDBRemoteLog.h */; }; + 2618EE6D1315B29C001D6D71 /* ThreadGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE631315B29C001D6D71 /* ThreadGDBRemote.cpp */; }; + 2618EE6E1315B29C001D6D71 /* ThreadGDBRemote.h in Headers */ = {isa = PBXBuildFile; fileRef = 2618EE641315B29C001D6D71 /* ThreadGDBRemote.h */; }; 261B5A5411C3F2AD00AABD0A /* SharingPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */; }; 262CFC7711A4510000946C6C /* debugserver in Resources */ = {isa = PBXBuildFile; fileRef = 26CE05A0115C31E50022F371 /* debugserver */; }; 2635DA87127D0D0400675BC1 /* SharingPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -258,11 +268,6 @@ 26D5B12E11B07550009A862E /* CommandObjectRegexCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DFBC59113B48F300DD817F /* CommandObjectRegexCommand.cpp */; }; 26D5B12F11B07550009A862E /* Symbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2689B0B5113EE47E00A4AEDB /* Symbols.cpp */; }; 26D5B13011B07550009A862E /* Debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263664921140A4930075843B /* Debugger.cpp */; }; - 26D5B13111B07550009A862E /* ProcessGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE62FA1145F2130064CF93 /* ProcessGDBRemote.cpp */; }; - 26D5B13211B07550009A862E /* ProcessGDBRemoteLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE62FC1145F2130064CF93 /* ProcessGDBRemoteLog.cpp */; }; - 26D5B13311B07550009A862E /* ThreadGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE62FE1145F2130064CF93 /* ThreadGDBRemote.cpp */; }; - 26D5B13411B07550009A862E /* GDBRemoteCommunication.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FE25221146CADE00F4085A /* GDBRemoteCommunication.cpp */; }; - 26D5B13511B07550009A862E /* GDBRemoteRegisterContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261E18CD1148966100BADCD3 /* GDBRemoteRegisterContext.cpp */; }; 26D5B13611B07550009A862E /* UnixSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00987011500B4300F316B0 /* UnixSignals.cpp */; }; 26D5B13711B07550009A862E /* LogChannelDWARF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26109B3B1155D70100CC3529 /* LogChannelDWARF.cpp */; }; 26D5B13811B07550009A862E /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */; }; @@ -553,10 +558,18 @@ 2618D7911240116900F2B8FE /* SectionLoadList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SectionLoadList.cpp; path = source/Target/SectionLoadList.cpp; sourceTree = ""; }; 2618D957124056C700F2B8FE /* NameToDIE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameToDIE.h; sourceTree = ""; }; 2618D9EA12406FE600F2B8FE /* NameToDIE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameToDIE.cpp; sourceTree = ""; }; + 2618EE5B1315B29C001D6D71 /* GDBRemoteCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunication.cpp; sourceTree = ""; }; + 2618EE5C1315B29C001D6D71 /* GDBRemoteCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunication.h; sourceTree = ""; }; + 2618EE5D1315B29C001D6D71 /* GDBRemoteRegisterContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteRegisterContext.cpp; sourceTree = ""; }; + 2618EE5E1315B29C001D6D71 /* GDBRemoteRegisterContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteRegisterContext.h; sourceTree = ""; }; + 2618EE5F1315B29C001D6D71 /* ProcessGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessGDBRemote.cpp; sourceTree = ""; }; + 2618EE601315B29C001D6D71 /* ProcessGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessGDBRemote.h; sourceTree = ""; }; + 2618EE611315B29C001D6D71 /* ProcessGDBRemoteLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessGDBRemoteLog.cpp; sourceTree = ""; }; + 2618EE621315B29C001D6D71 /* ProcessGDBRemoteLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessGDBRemoteLog.h; sourceTree = ""; }; + 2618EE631315B29C001D6D71 /* ThreadGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadGDBRemote.cpp; sourceTree = ""; }; + 2618EE641315B29C001D6D71 /* ThreadGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadGDBRemote.h; sourceTree = ""; }; 261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SharingPtr.cpp; path = source/Utility/SharingPtr.cpp; sourceTree = ""; }; 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharingPtr.h; path = include/lldb/Utility/SharingPtr.h; sourceTree = ""; }; - 261E18CC1148966100BADCD3 /* GDBRemoteRegisterContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GDBRemoteRegisterContext.h; path = "source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h"; sourceTree = ""; }; - 261E18CD1148966100BADCD3 /* GDBRemoteRegisterContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GDBRemoteRegisterContext.cpp; path = "source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp"; sourceTree = ""; }; 263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = ""; }; 263664941140A4C10075843B /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Debugger.h; path = include/lldb/Core/Debugger.h; sourceTree = ""; }; 26368A3B126B697600E8659F /* darwin-debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "darwin-debug.cpp"; path = "tools/darwin-debug/darwin-debug.cpp"; sourceTree = ""; }; @@ -936,8 +949,6 @@ 26F996A8119B79C300412154 /* ARM_GCC_Registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARM_GCC_Registers.h; path = source/Utility/ARM_GCC_Registers.h; sourceTree = ""; }; 26FA4315130103F400E71120 /* FileSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileSpec.h; path = include/lldb/Host/FileSpec.h; sourceTree = ""; }; 26FA43171301048600E71120 /* FileSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSpec.cpp; sourceTree = ""; }; - 26FE25221146CADE00F4085A /* GDBRemoteCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GDBRemoteCommunication.cpp; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp"; sourceTree = ""; }; - 26FE25231146CADE00F4085A /* GDBRemoteCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GDBRemoteCommunication.h; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h"; sourceTree = ""; }; 4906FD4012F2255300A2A77C /* ASTDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTDumper.cpp; path = source/Expression/ASTDumper.cpp; sourceTree = ""; }; 4906FD4412F2257600A2A77C /* ASTDumper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTDumper.h; path = include/lldb/Expression/ASTDumper.h; sourceTree = ""; }; 4911934B1226383D00578B7F /* ASTStructExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTStructExtractor.h; path = include/lldb/Expression/ASTStructExtractor.h; sourceTree = ""; }; @@ -1025,12 +1036,6 @@ 4CC2A148128C73ED001531C4 /* ThreadPlanTracer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanTracer.cpp; path = source/Target/ThreadPlanTracer.cpp; sourceTree = ""; }; 4CC2A14C128C7409001531C4 /* ThreadPlanTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanTracer.h; path = include/lldb/Target/ThreadPlanTracer.h; sourceTree = ""; }; 4CEDAED311754F5E00E875A6 /* ThreadPlanStepUntil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepUntil.h; path = include/lldb/Target/ThreadPlanStepUntil.h; sourceTree = ""; }; - 4CEE62FA1145F2130064CF93 /* ProcessGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessGDBRemote.cpp; path = "source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp"; sourceTree = ""; }; - 4CEE62FB1145F2130064CF93 /* ProcessGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProcessGDBRemote.h; path = "source/Plugins/Process/gdb-remote/ProcessGDBRemote.h"; sourceTree = ""; }; - 4CEE62FC1145F2130064CF93 /* ProcessGDBRemoteLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessGDBRemoteLog.cpp; path = "source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp"; sourceTree = ""; }; - 4CEE62FD1145F2130064CF93 /* ProcessGDBRemoteLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProcessGDBRemoteLog.h; path = "source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"; sourceTree = ""; }; - 4CEE62FE1145F2130064CF93 /* ThreadGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadGDBRemote.cpp; path = "source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp"; sourceTree = ""; }; - 4CEE62FF1145F2130064CF93 /* ThreadGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadGDBRemote.h; path = "source/Plugins/Process/gdb-remote/ThreadGDBRemote.h"; sourceTree = ""; }; 69A01E1B1236C5D400C660B5 /* Condition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Condition.cpp; sourceTree = ""; }; 69A01E1C1236C5D400C660B5 /* Host.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Host.cpp; sourceTree = ""; }; 69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = ""; }; @@ -2263,19 +2268,19 @@ 4CEE62F71145F1C70064CF93 /* GDB Remote */ = { isa = PBXGroup; children = ( - 26FE25231146CADE00F4085A /* GDBRemoteCommunication.h */, - 26FE25221146CADE00F4085A /* GDBRemoteCommunication.cpp */, - 261E18CC1148966100BADCD3 /* GDBRemoteRegisterContext.h */, - 261E18CD1148966100BADCD3 /* GDBRemoteRegisterContext.cpp */, - 4CEE62FB1145F2130064CF93 /* ProcessGDBRemote.h */, - 4CEE62FA1145F2130064CF93 /* ProcessGDBRemote.cpp */, - 4CEE62FD1145F2130064CF93 /* ProcessGDBRemoteLog.h */, - 4CEE62FC1145F2130064CF93 /* ProcessGDBRemoteLog.cpp */, - 4CEE62FF1145F2130064CF93 /* ThreadGDBRemote.h */, - 4CEE62FE1145F2130064CF93 /* ThreadGDBRemote.cpp */, + 2618EE5B1315B29C001D6D71 /* GDBRemoteCommunication.cpp */, + 2618EE5C1315B29C001D6D71 /* GDBRemoteCommunication.h */, + 2618EE5D1315B29C001D6D71 /* GDBRemoteRegisterContext.cpp */, + 2618EE5E1315B29C001D6D71 /* GDBRemoteRegisterContext.h */, + 2618EE5F1315B29C001D6D71 /* ProcessGDBRemote.cpp */, + 2618EE601315B29C001D6D71 /* ProcessGDBRemote.h */, + 2618EE611315B29C001D6D71 /* ProcessGDBRemoteLog.cpp */, + 2618EE621315B29C001D6D71 /* ProcessGDBRemoteLog.h */, + 2618EE631315B29C001D6D71 /* ThreadGDBRemote.cpp */, + 2618EE641315B29C001D6D71 /* ThreadGDBRemote.h */, ); name = "GDB Remote"; - path = ../../..; + path = "gdb-remote"; sourceTree = ""; }; 69A01E1A1236C5D400C660B5 /* common */ = { @@ -2360,6 +2365,11 @@ 26FA4316130103F400E71120 /* FileSpec.h in Headers */, 260C6EA113011578005E16B0 /* File.h in Headers */, 4C626534130F1B0A00C889F6 /* StreamTee.h in Headers */, + 2618EE661315B29C001D6D71 /* GDBRemoteCommunication.h in Headers */, + 2618EE681315B29C001D6D71 /* GDBRemoteRegisterContext.h in Headers */, + 2618EE6A1315B29C001D6D71 /* ProcessGDBRemote.h in Headers */, + 2618EE6C1315B29C001D6D71 /* ProcessGDBRemoteLog.h in Headers */, + 2618EE6E1315B29C001D6D71 /* ThreadGDBRemote.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2737,11 +2747,6 @@ 26D5B12E11B07550009A862E /* CommandObjectRegexCommand.cpp in Sources */, 26D5B12F11B07550009A862E /* Symbols.cpp in Sources */, 26D5B13011B07550009A862E /* Debugger.cpp in Sources */, - 26D5B13111B07550009A862E /* ProcessGDBRemote.cpp in Sources */, - 26D5B13211B07550009A862E /* ProcessGDBRemoteLog.cpp in Sources */, - 26D5B13311B07550009A862E /* ThreadGDBRemote.cpp in Sources */, - 26D5B13411B07550009A862E /* GDBRemoteCommunication.cpp in Sources */, - 26D5B13511B07550009A862E /* GDBRemoteRegisterContext.cpp in Sources */, 26D5B13611B07550009A862E /* UnixSignals.cpp in Sources */, 26D5B13711B07550009A862E /* LogChannelDWARF.cpp in Sources */, 26D5B13811B07550009A862E /* PseudoTerminal.cpp in Sources */, @@ -2866,6 +2871,11 @@ 268DA874130095ED00C9483A /* Terminal.cpp in Sources */, 26FA43181301048600E71120 /* FileSpec.cpp in Sources */, 260C6EA313011581005E16B0 /* File.cpp in Sources */, + 2618EE651315B29C001D6D71 /* GDBRemoteCommunication.cpp in Sources */, + 2618EE671315B29C001D6D71 /* GDBRemoteRegisterContext.cpp in Sources */, + 2618EE691315B29C001D6D71 /* ProcessGDBRemote.cpp in Sources */, + 2618EE6B1315B29C001D6D71 /* ProcessGDBRemoteLog.cpp in Sources */, + 2618EE6D1315B29C001D6D71 /* ThreadGDBRemote.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 7e18e124d678..9b2b2a4246d3 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -163,52 +163,69 @@ public: // If our listener is NULL, users aren't allows to launch char filename[PATH_MAX]; const Module *exe_module = target->GetExecutableModule().get(); + + if (exe_module == NULL) + { + result.AppendError ("no file in target, set executable file using 'file' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); + StateType state = eStateInvalid; Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; - if (process && process->IsAlive()) - { - char message[1024]; - if (process->GetState() == eStateAttaching) - ::strncpy (message, "There is a pending attach, abort it and launch a new process?", sizeof(message)); - else - ::strncpy (message, "There is a running process, kill it and restart?", sizeof(message)); - - if (!m_interpreter.Confirm (message, true)) - { - result.SetStatus (eReturnStatusFailed); - return false; - } - else - { - Error error (process->Destroy()); - if (error.Success()) + if (process) + { + state = process->GetState(); + + if (process->IsAlive() && state != eStateConnected) + { + char message[1024]; + if (process->GetState() == eStateAttaching) + ::strncpy (message, "There is a pending attach, abort it and launch a new process?", sizeof(message)); + else + ::strncpy (message, "There is a running process, kill it and restart?", sizeof(message)); + + if (!m_interpreter.Confirm (message, true)) { - result.SetStatus (eReturnStatusSuccessFinishResult); + result.SetStatus (eReturnStatusFailed); + return false; } else { - result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); - result.SetStatus (eReturnStatusFailed); + Error error (process->Destroy()); + if (error.Success()) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } } } } - const char *plugin_name; - if (!m_options.plugin_name.empty()) - plugin_name = m_options.plugin_name.c_str(); - else - plugin_name = NULL; - - process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); - - if (process == NULL) + if (state != eStateConnected) { - result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); - result.SetStatus (eReturnStatusFailed); - return false; + const char *plugin_name; + if (!m_options.plugin_name.empty()) + plugin_name = m_options.plugin_name.c_str(); + else + plugin_name = NULL; + + process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); + if (process == NULL) + { + result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); + result.SetStatus (eReturnStatusFailed); + return false; + } } + // If no launch args were given on the command line, then use any that // might have been set using the "run-args" set variable. if (launch_args.GetArgumentCount() == 0) @@ -219,16 +236,24 @@ public: if (m_options.in_new_tty) { - char exec_file_path[PATH_MAX]; - if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) + if (state == eStateConnected) { - launch_args.InsertArgumentAtIndex(0, exec_file_path); + result.AppendWarning("launch in tty option is ignored when launching through a remote connection"); + m_options.in_new_tty = false; } else { - result.AppendError("invalid executable"); - result.SetStatus (eReturnStatusFailed); - return false; + char exec_file_path[PATH_MAX]; + if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) + { + launch_args.InsertArgumentAtIndex(0, exec_file_path); + } + else + { + result.AppendError("invalid executable"); + result.SetStatus (eReturnStatusFailed); + return false; + } } } @@ -563,9 +588,11 @@ public: bool synchronous_execution = m_interpreter.GetSynchronous (); Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; + StateType state = eStateInvalid; if (process) { - if (process->IsAlive()) + state = process->GetState(); + if (process->IsAlive() && state != eStateConnected) { result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", process->GetID()); @@ -610,12 +637,15 @@ public: } else { - const char *plugin_name = NULL; - - if (!m_options.plugin_name.empty()) - plugin_name = m_options.plugin_name.c_str(); + if (state != eStateConnected) + { + const char *plugin_name = NULL; + + if (!m_options.plugin_name.empty()) + plugin_name = m_options.plugin_name.c_str(); - process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); + process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); + } if (process) { @@ -1503,7 +1533,10 @@ public: } else { - output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); + if (state == eStateConnected) + output_stream.Printf ("Connected to remote target.\n"); + else + output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); if (exe_ctx.thread == NULL) exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); if (exe_ctx.thread != NULL) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 126b60f2f70d..004beb6ea17d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -515,6 +515,7 @@ GDBRemoteCommunication::SendContinuePacketAndWaitForResponse default: if (log) log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__); + state = eStateInvalid; break; } } @@ -908,7 +909,7 @@ GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeou if (i > 0) packet.PutChar(','); packet.Printf("%i,%i,", arg_len * 2, i); - packet.PutBytesAsRawHex8(arg, arg_len, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder()); + packet.PutBytesAsRawHex8 (arg, arg_len); } StringExtractorGDBRemote response; @@ -1101,3 +1102,108 @@ GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds) return false; } +int +GDBRemoteCommunication::SetSTDIN (char const *path) +{ + if (path && path[0]) + { + StreamString packet; + packet.PutCString("QSetSTDIN:"); + packet.PutBytesAsRawHex8(path, strlen(path)); + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false)) + { + if (response.IsOKPacket()) + return 0; + uint8_t error = response.GetError(); + if (error) + return error; + } + } + return -1; +} + +int +GDBRemoteCommunication::SetSTDOUT (char const *path) +{ + if (path && path[0]) + { + StreamString packet; + packet.PutCString("QSetSTDOUT:"); + packet.PutBytesAsRawHex8(path, strlen(path)); + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false)) + { + if (response.IsOKPacket()) + return 0; + uint8_t error = response.GetError(); + if (error) + return error; + } + } + return -1; +} + +int +GDBRemoteCommunication::SetSTDERR (char const *path) +{ + if (path && path[0]) + { + StreamString packet; + packet.PutCString("QSetSTDERR:"); + packet.PutBytesAsRawHex8(path, strlen(path)); + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false)) + { + if (response.IsOKPacket()) + return 0; + uint8_t error = response.GetError(); + if (error) + return error; + } + } + return -1; +} + +int +GDBRemoteCommunication::SetWorkingDir (char const *path) +{ + if (path && path[0]) + { + StreamString packet; + packet.PutCString("QSetWorkingDir:"); + packet.PutBytesAsRawHex8(path, strlen(path)); + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false)) + { + if (response.IsOKPacket()) + return 0; + uint8_t error = response.GetError(); + if (error) + return error; + } + } + return -1; +} + +int +GDBRemoteCommunication::SetDisableASLR (bool enable) +{ + StreamString packet; + packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0); + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, 1, false)) + { + if (response.IsOKPacket()) + return 0; + uint8_t error = response.GetError(); + if (error) + return error; + } + return -1; +} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 1499ba90443a..8d24f2ad4423 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -196,6 +196,49 @@ public: StringExtractorGDBRemote& response); + //------------------------------------------------------------------ + /// Sets the path to use for stdin/out/err for a process + /// that will be launched with the 'A' packet. + /// + /// @param[in] path + /// The path to use for stdin/out/err + /// + /// @return + /// Zero if the for success, or an error code for failure. + //------------------------------------------------------------------ + int + SetSTDIN (char const *path); + int + SetSTDOUT (char const *path); + int + SetSTDERR (char const *path); + + //------------------------------------------------------------------ + /// Sets the disable ASLR flag to \a enable for a process that will + /// be launched with the 'A' packet. + /// + /// @param[in] enable + /// A boolean value indicating wether to disable ASLR or not. + /// + /// @return + /// Zero if the for success, or an error code for failure. + //------------------------------------------------------------------ + int + SetDisableASLR (bool enable); + + //------------------------------------------------------------------ + /// Sets the working directory to \a path for a process that will + /// be launched with the 'A' packet. + /// + /// @param[in] path + /// The path to a directory to use when launching our processs + /// + /// @return + /// Zero if the for success, or an error code for failure. + //------------------------------------------------------------------ + int + SetWorkingDir (char const *path); + lldb::addr_t AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 34eca44081ae..20afb62717c4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -440,113 +440,122 @@ ProcessGDBRemote::DoLaunch char connect_url[128]; snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); - const bool launch_process = true; - bool start_debugserver_with_inferior_args = false; - if (start_debugserver_with_inferior_args) - { - // We want to launch debugserver with the inferior program and its - // arguments on the command line. We should only do this if we - // the GDB server we are talking to doesn't support the 'A' packet. - error = StartDebugserverProcess (host_port, - argv, - envp, - stdin_path, - stdout_path, - stderr_path, - working_dir, - launch_process, - LLDB_INVALID_PROCESS_ID, - NULL, false, - launch_flags, - inferior_arch); - if (error.Fail()) - return error; - - error = ConnectToDebugserver (connect_url); - if (error.Success()) - { - SetID (m_gdb_comm.GetCurrentProcessID (m_packet_timeout)); - } - } - else + // Make sure we aren't already connected? + if (!m_gdb_comm.IsConnected()) { error = StartDebugserverProcess (host_port, NULL, NULL, - stdin_path, - stdout_path, - stderr_path, - working_dir, - launch_process, LLDB_INVALID_PROCESS_ID, NULL, false, - launch_flags, inferior_arch); if (error.Fail()) return error; error = ConnectToDebugserver (connect_url); - if (error.Success()) + } + + if (error.Success()) + { + lldb_utility::PseudoTerminal pty; + const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; + if (disable_stdio) { - // Send the environment and the program + arguments after we connect - if (envp) + stdin_path = "/dev/null"; + stdout_path = "/dev/null"; + stderr_path = "/dev/null"; + } + else + { + const char *slave_name = NULL; + if (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL) { - const char *env_entry; - for (int i=0; (env_entry = envp[i]); ++i) - { - if (m_gdb_comm.SendEnvironmentPacket(env_entry, m_packet_timeout) != 0) - break; - } + if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0)) + slave_name = pty.GetSlaveName (NULL, 0); } + if (stdin_path == NULL) + stdin_path = slave_name; - // FIXME: convert this to use the new set/show variables when they are available -#if 0 - if (::getenv ("LLDB_DEBUG_DEBUGSERVER")) + if (stdout_path == NULL) + stdout_path = slave_name; + + if (stderr_path == NULL) + stderr_path = slave_name; + } + + if (stdin_path == NULL && (stdout_path || stderr_path)) + stdin_path = "/dev/null"; + + if (stdout_path == NULL && (stdin_path || stderr_path)) + stdout_path = "/dev/null"; + + if (stderr_path == NULL && (stdin_path || stdout_path)) + stderr_path = "/dev/null"; + + if (stdin_path) + m_gdb_comm.SetSTDIN (stdin_path); + if (stdout_path) + m_gdb_comm.SetSTDOUT (stdout_path); + if (stderr_path) + m_gdb_comm.SetSTDERR (stderr_path); + + m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR); + + + if (working_dir && working_dir[0]) + { + m_gdb_comm.SetWorkingDir (working_dir); + } + + // Send the environment and the program + arguments after we connect + if (envp) + { + const char *env_entry; + for (int i=0; (env_entry = envp[i]); ++i) { - const uint32_t attach_debugserver_secs = 10; - ::printf ("attach to debugserver (pid = %i)\n", m_debugserver_pid); - for (uint32_t i=0; i %zu )", cpu, ocount); - - if (error.Fail() != 0 || ocount != 1) - return error; - } - -#endif - Args debugserver_args; char arg_cstr[PATH_MAX]; - lldb_utility::PseudoTerminal pty; - const char *stdio_path = NULL; - if (launch_process && - (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL) && - m_local_debugserver && - no_stdio == false) - { - if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0)) - { - const char *slave_name = pty.GetSlaveName (NULL, 0); - if (stdin_path == NULL - && stdout_path == NULL - && stderr_path == NULL) - stdio_path = slave_name; - else - { - if (stdin_path == NULL) - stdin_path = slave_name; - if (stdout_path == NULL) - stdout_path = slave_name; - if (stderr_path == NULL) - stderr_path = slave_name; - } - } - } - // Start args with "debugserver /file/path -r --" debugserver_args.AppendArgument(debugserver_path); debugserver_args.AppendArgument(debugserver_url); @@ -2025,66 +1977,6 @@ ProcessGDBRemote::StartDebugserverProcess // special terminal key sequences (^C) don't affect debugserver debugserver_args.AppendArgument("--setsid"); - if (disable_aslr) - debugserver_args.AppendArguments("--disable-aslr"); - - // Only set the inferior - if (launch_process) - { - if (no_stdio) - debugserver_args.AppendArgument("--no-stdio"); - else - { - if (stdin_path && stdout_path && stderr_path && - strcmp(stdin_path, stdout_path) == 0 && - strcmp(stdin_path, stderr_path) == 0) - { - stdio_path = stdin_path; - stdin_path = stdout_path = stderr_path = NULL; - } - - if (stdio_path) - { - // All file handles to stdin, stdout, stderr are the same... - debugserver_args.AppendArgument("--stdio-path"); - debugserver_args.AppendArgument(stdio_path); - } - else - { - if (stdin_path == NULL && (stdout_path || stderr_path)) - stdin_path = "/dev/null"; - - if (stdout_path == NULL && (stdin_path || stderr_path)) - stdout_path = "/dev/null"; - - if (stderr_path == NULL && (stdin_path || stdout_path)) - stderr_path = "/dev/null"; - - if (stdin_path) - { - debugserver_args.AppendArgument("--stdin-path"); - debugserver_args.AppendArgument(stdin_path); - } - if (stdout_path) - { - debugserver_args.AppendArgument("--stdout-path"); - debugserver_args.AppendArgument(stdout_path); - } - if (stderr_path) - { - debugserver_args.AppendArgument("--stderr-path"); - debugserver_args.AppendArgument(stderr_path); - } - } - } - } - - if (working_dir) - { - debugserver_args.AppendArgument("--working-dir"); - debugserver_args.AppendArgument(working_dir); - } - const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); if (env_debugserver_log_file) { @@ -2102,21 +1994,13 @@ ProcessGDBRemote::StartDebugserverProcess // debugserver_args.AppendArgument("--log-flags=0x802e0e"); // Now append the program arguments - if (launch_process) + if (inferior_argv) { - if (inferior_argv) - { - // Terminate the debugserver args so we can now append the inferior args - debugserver_args.AppendArgument("--"); + // Terminate the debugserver args so we can now append the inferior args + debugserver_args.AppendArgument("--"); - for (int i = 0; inferior_argv[i] != NULL; ++i) - debugserver_args.AppendArgument (inferior_argv[i]); - } - else - { - // Will send environment entries with the 'QEnvironment:' packet - // Will send arguments with the 'A' packet - } + for (int i = 0; inferior_argv[i] != NULL; ++i) + debugserver_args.AppendArgument (inferior_argv[i]); } else if (attach_pid != LLDB_INVALID_PROCESS_ID) { @@ -2175,11 +2059,6 @@ ProcessGDBRemote::StartDebugserverProcess if (error.Fail() || log) error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", m_debugserver_pid, debugserver_path, NULL, &attr, inferior_argv, inferior_envp); - if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID && !no_stdio) - { - if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd) - SetUpProcessInputReader (pty.ReleaseMasterFileDescriptor()); - } } else { @@ -2399,6 +2278,8 @@ ProcessGDBRemote::AsyncThread (void *arg) if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask) { + listener.StartListeningForEvents (&process->m_gdb_comm, Communication::eBroadcastBitReadThreadDidExit); + bool done = false; while (!done) { @@ -2407,67 +2288,79 @@ ProcessGDBRemote::AsyncThread (void *arg) if (listener.WaitForEvent (NULL, event_sp)) { const uint32_t event_type = event_sp->GetType(); - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type); - - switch (event_type) + if (event_sp->BroadcasterIs (&process->m_async_broadcaster)) { - case eBroadcastBitAsyncContinue: - { - const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get()); + if (log) + log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type); - if (continue_packet) + switch (event_type) + { + case eBroadcastBitAsyncContinue: { - const char *continue_cstr = (const char *)continue_packet->GetBytes (); - const size_t continue_cstr_len = continue_packet->GetByteSize (); - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr); + const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get()); - if (::strstr (continue_cstr, "vAttach") == NULL) - process->SetPrivateState(eStateRunning); - StringExtractorGDBRemote response; - StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response); - - switch (stop_state) + if (continue_packet) { - case eStateStopped: - case eStateCrashed: - case eStateSuspended: - process->m_last_stop_packet = response; - process->m_last_stop_packet.SetFilePos (0); - process->SetPrivateState (stop_state); - break; + const char *continue_cstr = (const char *)continue_packet->GetBytes (); + const size_t continue_cstr_len = continue_packet->GetByteSize (); + if (log) + log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr); - case eStateExited: - process->m_last_stop_packet = response; - process->m_last_stop_packet.SetFilePos (0); - response.SetFilePos(1); - process->SetExitStatus(response.GetHexU8(), NULL); - done = true; - break; + if (::strstr (continue_cstr, "vAttach") == NULL) + process->SetPrivateState(eStateRunning); + StringExtractorGDBRemote response; + StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response); - case eStateInvalid: - break; + switch (stop_state) + { + case eStateStopped: + case eStateCrashed: + case eStateSuspended: + process->m_last_stop_packet = response; + process->m_last_stop_packet.SetFilePos (0); + process->SetPrivateState (stop_state); + break; - default: - process->SetPrivateState (stop_state); - break; + case eStateExited: + process->m_last_stop_packet = response; + process->m_last_stop_packet.SetFilePos (0); + response.SetFilePos(1); + process->SetExitStatus(response.GetHexU8(), NULL); + done = true; + break; + + case eStateInvalid: + process->SetExitStatus(-1, "lost connection"); + break; + + default: + process->SetPrivateState (stop_state); + break; + } } } - } - break; + break; - case eBroadcastBitAsyncThreadShouldExit: - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID()); - done = true; - break; + case eBroadcastBitAsyncThreadShouldExit: + if (log) + log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID()); + done = true; + break; - default: - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type); + default: + if (log) + log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type); + done = true; + break; + } + } + else if (event_sp->BroadcasterIs (&process->m_gdb_comm)) + { + if (event_type & Communication::eBroadcastBitReadThreadDidExit) + { + process->SetExitStatus (-1, "lost connection"); done = true; - break; + } } } else diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 7d5a361e98b1..bd61ed248688 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -293,16 +293,10 @@ protected: StartDebugserverProcess (const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...") char const *inferior_argv[], char const *inferior_envp[], - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - const char *working_dir, - bool launch_process, // Set to true if we are going to be launching a the process lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, then attach to this pid const char *attach_pid_name, // Wait for the next process to launch whose basename matches "attach_wait_name" bool wait_for_launch, // Wait for the process named "attach_wait_name" to launch - uint32_t launch_flags, - lldb_private::ArchSpec& arch_spec); + const lldb_private::ArchSpec& arch_spec); void KillDebugserverProcess (); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 7a0de0b03efc..6d2861d32353 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1512,6 +1512,9 @@ Process::Launch exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path)); if (exe_module->GetFileSpec().Exists()) { + if (PrivateStateThreadIsValid ()) + PausePrivateStateThread (); + error = WillLaunch (exe_module); if (error.Success()) { @@ -1579,7 +1582,11 @@ Process::Launch // This delays passing the stopped event to listeners till DidLaunch gets // a chance to complete... HandlePrivateEvent (event_sp); - StartPrivateStateThread (); + + if (PrivateStateThreadIsValid ()) + ResumePrivateStateThread (); + else + StartPrivateStateThread (); } else if (state == eStateExited) { @@ -1605,6 +1612,7 @@ Process::AttachCompletionHandler::PerformAction (lldb::EventSP &event_sp) switch (state) { case eStateRunning: + case eStateConnected: return eEventActionRetry; case eStateStopped: @@ -1776,31 +1784,13 @@ Process::ConnectRemote (const char *remote_url) Error error (DoConnectRemote (remote_url)); if (error.Success()) { - SetNextEventAction(new Process::AttachCompletionHandler(this)); - StartPrivateStateThread(); -// TimeValue timeout; -// timeout = TimeValue::Now(); -// timeout.OffsetWithMicroSeconds(000); -// EventSP event_sp; -// StateType state = WaitForProcessStopPrivate(NULL, event_sp); -// -// if (state == eStateStopped || state == eStateCrashed) -// { -// DidLaunch (); -// -// // This delays passing the stopped event to listeners till DidLaunch gets -// // a chance to complete... -// HandlePrivateEvent (event_sp); -// StartPrivateStateThread (); -// } -// else if (state == eStateExited) -// { -// // We exited while trying to launch somehow. Don't call DidLaunch as that's -// // not likely to work, and return an invalid pid. -// HandlePrivateEvent (event_sp); -// } -// -// StartPrivateStateThread(); + StartPrivateStateThread(); + // If we attached and actually have a process on the other end, then + // this ended up being the equivalent of an attach. + if (GetID() != LLDB_INVALID_PROCESS_ID) + { + CompleteAttach (); + } } return error; } diff --git a/lldb/source/Utility/StringExtractor.cpp b/lldb/source/Utility/StringExtractor.cpp index c410ffd39b13..b783c0762ac6 100644 --- a/lldb/source/Utility/StringExtractor.cpp +++ b/lldb/source/Utility/StringExtractor.cpp @@ -146,8 +146,8 @@ StringExtractor::GetHexU8 (uint8_t fail_value) if (isxdigit(hi_nibble_char) && isxdigit(lo_nibble_char)) { - uint8_t hi_nibble = xdigit_to_sint (hi_nibble_char); - uint8_t lo_nibble = xdigit_to_sint (lo_nibble_char); + uint8_t hi_nibble = xdigit_to_uint (hi_nibble_char); + uint8_t lo_nibble = xdigit_to_uint (lo_nibble_char); m_index += 2; return (hi_nibble << 4) + lo_nibble; } diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index fab4741ac108..635442754c6f 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -1971,6 +1971,16 @@ DNBProcessGetStopCount (nub_process_t pid) return 0; } +uint32_t +DNBProcessGetCPUType (nub_process_t pid) +{ + MachProcessSP procSP; + if (GetProcessSP (pid, procSP)) + return procSP->GetCPUType (); + return 0; + +} + nub_bool_t DNBResolveExecutablePath (const char *path, char *resolved_path, size_t resolved_path_size) { diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h index 2b2389d9cdc2..e9a3f341d197 100644 --- a/lldb/tools/debugserver/source/DNB.h +++ b/lldb/tools/debugserver/source/DNB.h @@ -86,6 +86,7 @@ nub_addr_t DNBProcessLookupAddress (nub_process_t pid, cons nub_size_t DNBProcessGetAvailableSTDOUT (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT; nub_size_t DNBProcessGetAvailableSTDERR (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT; nub_size_t DNBProcessGetStopCount (nub_process_t pid) DNB_EXPORT; +uint32_t DNBProcessGetCPUType (nub_process_t pid) DNB_EXPORT; //---------------------------------------------------------------------- // Process executable and arguments //---------------------------------------------------------------------- diff --git a/lldb/tools/debugserver/source/DNBArch.cpp b/lldb/tools/debugserver/source/DNBArch.cpp index 11743916b137..f56c6a3181ef 100644 --- a/lldb/tools/debugserver/source/DNBArch.cpp +++ b/lldb/tools/debugserver/source/DNBArch.cpp @@ -21,10 +21,12 @@ typedef std::map CPUPluginInfoMap; -#if defined (__i386__) -static uint32_t g_current_cpu_type = CPU_TYPE_I386; -#elif defined (__x86_64__) -static uint32_t g_current_cpu_type = CPU_TYPE_X86_64; +//#if defined (__i386__) +//static uint32_t g_current_cpu_type = CPU_TYPE_I386; +//#elif defined (__x86_64__) +//static uint32_t g_current_cpu_type = CPU_TYPE_X86_64; +#if defined (__i386__) || defined (__x86_64__) +static uint32_t g_current_cpu_type = 0; #elif defined (__arm__) static uint32_t g_current_cpu_type = CPU_TYPE_ARM; #else diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp index 12c981bccb46..1c002c2f58d2 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "MacOSX/CFUtils.h" #include "SysSignal.h" @@ -91,6 +92,7 @@ IsSBProcess (nub_process_t pid) MachProcess::MachProcess() : m_pid (0), + m_cpu_type (0), m_child_stdin (-1), m_child_stdout (-1), m_child_stderr (-1), @@ -200,6 +202,14 @@ MachProcess::GetThreadInfo(nub_thread_t tid) const return m_thread_list.GetThreadInfo(tid); } +uint32_t +MachProcess::GetCPUType () +{ + if (m_cpu_type == 0 && m_pid != 0) + m_cpu_type = MachProcess::GetCPUTypeForLocalProcess (m_pid); + return m_cpu_type; +} + const DNBRegisterSetInfo * MachProcess::GetRegisterSetInfo (nub_thread_t tid, nub_size_t *num_reg_sets) const { @@ -1662,14 +1672,16 @@ MachProcess::PosixSpawnChildForPTraceDebugging // We don't need to do this for ARM, and we really shouldn't now that we // have multiple CPU subtypes and no posix_spawnattr call that allows us // to set which CPU subtype to launch... - size_t ocount = 0; - err.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount), DNBError::POSIX); - if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS)) - err.LogThreaded("::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu_type, ocount); - - if (err.Fail() != 0 || ocount != 1) - return INVALID_NUB_PROCESS; + if (cpu_type != 0) + { + size_t ocount = 0; + err.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount), DNBError::POSIX); + if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS)) + err.LogThreaded("::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu_type, ocount); + if (err.Fail() != 0 || ocount != 1) + return INVALID_NUB_PROCESS; + } #endif PseudoTerminal pty; @@ -1712,21 +1724,25 @@ MachProcess::PosixSpawnChildForPTraceDebugging } else { - int slave_fd_err = open (stderr_path ? stderr_path : "/dev/null", O_NOCTTY | O_CREAT | O_RDWR , 0640); - int slave_fd_in = open (stdin_path ? stdin_path : "/dev/null", O_NOCTTY | O_RDONLY); - int slave_fd_out = open (stdout_path ? stdout_path : "/dev/null", O_NOCTTY | O_CREAT | O_WRONLY , 0640); + if ( stdin_path == NULL) stdin_path = "/dev/null"; + if (stdout_path == NULL) stdout_path = "/dev/null"; + if (stderr_path == NULL) stderr_path = "/dev/null"; + + int slave_fd_err = open (stderr_path, O_NOCTTY | O_CREAT | O_RDWR , 0640); + int slave_fd_in = open (stdin_path , O_NOCTTY | O_RDONLY); + int slave_fd_out = open (stdout_path, O_NOCTTY | O_CREAT | O_WRONLY , 0640); err.SetError( ::posix_spawn_file_actions_adddup2(&file_actions, slave_fd_err, STDERR_FILENO), DNBError::POSIX); if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS)) - err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d, newfiledes = STDERR_FILENO )", slave_fd_err); + err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d (\"%s\"), newfiledes = STDERR_FILENO )", slave_fd_err, stderr_path); err.SetError( ::posix_spawn_file_actions_adddup2(&file_actions, slave_fd_in, STDIN_FILENO), DNBError::POSIX); if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS)) - err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d, newfiledes = STDIN_FILENO )", slave_fd_in); + err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d (\"%s\"), newfiledes = STDIN_FILENO )", slave_fd_in, stdin_path); err.SetError( ::posix_spawn_file_actions_adddup2(&file_actions, slave_fd_out, STDOUT_FILENO), DNBError::POSIX); if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS)) - err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d, newfiledes = STDOUT_FILENO )", slave_fd_out); + err.LogThreaded("::posix_spawn_file_actions_adddup2 ( &file_actions, filedes = %d (\"%s\"), newfiledes = STDOUT_FILENO )", slave_fd_out, stdout_path); } // TODO: Verify if we can set the working directory back immediately @@ -1763,9 +1779,16 @@ MachProcess::PosixSpawnChildForPTraceDebugging process->SetChildFileDescriptors(master_fd, master_fd, master_fd); } } - ::posix_spawnattr_destroy (&attr); + if (pid != INVALID_NUB_PROCESS) + { + cpu_type_t pid_cpu_type = MachProcess::GetCPUTypeForLocalProcess (pid); + DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( ) pid=%i, cpu_type=0x%8.8x", __FUNCTION__, pid, pid_cpu_type); + if (pid_cpu_type) + DNBArchProtocol::SetArchitecture (pid_cpu_type); + } + if (file_actions_valid) { DNBError err2; @@ -1777,6 +1800,24 @@ MachProcess::PosixSpawnChildForPTraceDebugging return pid; } +uint32_t +MachProcess::GetCPUTypeForLocalProcess (pid_t pid) +{ + int mib[CTL_MAXNAME]={0,}; + size_t len = CTL_MAXNAME; + if (::sysctlnametomib("sysctl.proc_cputype", mib, &len)) + return 0; + + mib[len] = pid; + len++; + + cpu_type_t cpu; + size_t cpu_len = sizeof(cpu); + if (::sysctl (mib, len, &cpu, &cpu_len, 0, 0)) + cpu = 0; + return cpu; +} + pid_t MachProcess::ForkChildForPTraceDebugging ( diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h index 85a8b4673829..d52735adba71 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -58,6 +58,8 @@ public: nub_launch_flavor_t launch_flavor, int disable_aslr, DNBError &err); + + static uint32_t GetCPUTypeForLocalProcess (pid_t pid); static pid_t ForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], MachProcess* process, DNBError &err); static pid_t PosixSpawnChildForPTraceDebugging (const char *path, cpu_type_t cpu_type, @@ -167,6 +169,7 @@ public: void DumpThreadStoppedReason(nub_thread_t tid) const; const char * GetThreadInfo (nub_thread_t tid) const; + uint32_t GetCPUType (); nub_state_t GetState (); void SetState (nub_state_t state); bool IsRunning (nub_state_t state) @@ -248,6 +251,7 @@ private: nub_state_t DoSIGSTOP (bool clear_bps_and_wps, uint32_t *thread_idx_ptr = NULL); pid_t m_pid; // Process ID of child process + cpu_type_t m_cpu_type; // The CPU type of this process int m_child_stdin; int m_child_stdout; int m_child_stderr; diff --git a/lldb/tools/debugserver/source/RNBContext.h b/lldb/tools/debugserver/source/RNBContext.h index 93b98de9a7dc..0044d19ca9a3 100644 --- a/lldb/tools/debugserver/source/RNBContext.h +++ b/lldb/tools/debugserver/source/RNBContext.h @@ -104,12 +104,25 @@ public: } bool SetWorkingDirectory (const char *path); - + + std::string& GetSTDIN () { return m_stdin; } + std::string& GetSTDOUT () { return m_stdout; } + std::string& GetSTDERR () { return m_stderr; } + std::string& GetWorkingDir () { return m_working_dir; } + + const char * GetSTDINPath() { return m_stdin.empty() ? NULL : m_stdin.c_str(); } + const char * GetSTDOUTPath() { return m_stdout.empty() ? NULL : m_stdout.c_str(); } + const char * GetSTDERRPath() { return m_stderr.empty() ? NULL : m_stderr.c_str(); } + const char * GetWorkingDirPath() { return m_working_dir.empty() ? NULL : m_working_dir.c_str(); } protected: //------------------------------------------------------------------ // Classes that inherit from RNBContext can see and modify these //------------------------------------------------------------------ nub_process_t m_pid; + std::string m_stdin; + std::string m_stdout; + std::string m_stderr; + std::string m_working_dir; nub_size_t m_pid_stop_count; PThreadEvent m_events; // Threaded events that we can wait for pthread_t m_pid_pthread; diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 1d6d0883c233..465abcb90768 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "DNB.h" @@ -60,10 +61,9 @@ extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); -RNBRemote::RNBRemote (bool use_native_regs, const char *arch) : +RNBRemote::RNBRemote () : m_ctx (), m_comm (), - m_arch (), m_continue_thread(-1), m_thread(-1), m_mutex(), @@ -77,12 +77,10 @@ RNBRemote::RNBRemote (bool use_native_regs, const char *arch) : m_extended_mode(false), m_noack_mode(false), m_thread_suffix_supported (false), - m_use_native_regs (use_native_regs) + m_use_native_regs (false) { DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); CreatePacketTable (); - if (arch && arch[0]) - m_arch.assign (arch); } @@ -178,6 +176,10 @@ RNBRemote::CreatePacketTable () t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle")); t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_QEnvironment , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment")); t.push_back (Packet (set_disable_aslr, &RNBRemote::HandlePacket_QSetDisableASLR , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet")); + t.push_back (Packet (set_stdin, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDIN:", "Set the standard input for a process to be launched with the 'A' packet")); + t.push_back (Packet (set_stdout, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDOUT:", "Set the standard output for a process to be launched with the 'A' packet")); + t.push_back (Packet (set_stderr, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDERR:", "Set the standard error for a process to be launched with the 'A' packet")); + t.push_back (Packet (set_working_dir, &RNBRemote::HandlePacket_QSetWorkingDir , NULL, "QSetWorkingDir:", "Set the working directory for a process to be launched with the 'A' packet")); // t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior")); t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process.")); t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process.")); @@ -1002,7 +1004,7 @@ RNBRemote::InitializeRegisters () if (m_use_native_regs) { - DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface (%s)", __FUNCTION__, m_arch.c_str()); + DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface", __FUNCTION__); // Discover the registers by querying the DNB interface and letting it // state the registers that it would like to export. This allows the // registers to be discovered using multiple qRegisterInfo calls to get @@ -1041,9 +1043,10 @@ RNBRemote::InitializeRegisters () } else { - DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting gdb registers (%s)", __FUNCTION__, m_arch.c_str()); + uint32_t cpu_type = DNBProcessGetCPUType (pid); + DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting gdb registers(%s)", __FUNCTION__, m_arch.c_str()); #if defined (__i386__) || defined (__x86_64__) - if (m_arch.compare("x86_64") == 0) + if (cpu_type == CPU_TYPE_X86_64) { const size_t num_regs = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t); for (uint32_t i=0; iContext(); - uint32_t event_mask = RNBContext::event_read_packet_available; + uint32_t event_mask = RNBContext::event_read_packet_available | + RNBContext::event_read_thread_exiting; // Spin waiting to get the A packet. while (1) @@ -83,6 +84,12 @@ RNBRunLoopGetStartModeFromRemote (RNBRemote* remote) nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask); DNBLogThreadedIf (LOG_RNB_MAX, "%s ctx.Events().WaitForSetEvents( 0x%08x ) => 0x%08x", __FUNCTION__, event_mask, set_events); + if (set_events & RNBContext::event_read_thread_exiting) + { + RNBLogSTDERR ("error: packet read thread exited."); + return eRNBRunLoopModeExit; + } + if (set_events & RNBContext::event_read_packet_available) { rnb_err_t err = rnb_err; @@ -219,7 +226,9 @@ RNBRunLoopLaunchInferior (RNBRemote *remote, const char *stdin_path, const char ctx.LaunchStatus().SetErrorString(launch_err_str); } else + { ctx.LaunchStatus().Clear(); + } if (remote->Comm().IsConnected()) { @@ -682,6 +691,18 @@ main (int argc, char *argv[]) signal (SIGPIPE, signal_handler); signal (SIGHUP, signal_handler); + g_remoteSP.reset (new RNBRemote ()); + + + RNBRemote *remote = g_remoteSP.get(); + if (remote == NULL) + { + RNBLogSTDERR ("error: failed to create a remote connection class\n"); + return -1; + } + + RNBContext& ctx = remote->Context(); + int i; int attach_pid = INVALID_NUB_PROCESS; @@ -690,14 +711,10 @@ main (int argc, char *argv[]) // Parse our options int ch; int long_option_index = 0; - int use_native_registers = 0; int debug = 0; std::string compile_options; std::string waitfor_pid_name; // Wait for a process that starts with this name std::string attach_pid_name; - std::string stdin_path; - std::string stdout_path; - std::string stderr_path; std::string arch_name; std::string working_dir; // The new working directory to use for the inferior useconds_t waitfor_interval = 1000; // Time in usecs between process lists polls when waiting for a process by name, default 1 msec. @@ -859,7 +876,7 @@ main (int argc, char *argv[]) break; case 'r': - use_native_registers = 1; + remote->SetUseNativeRegisters (true); break; case 'v': @@ -867,21 +884,21 @@ main (int argc, char *argv[]) break; case 's': - stdin_path.assign(optarg); - stdout_path.assign(optarg); - stderr_path.assign(optarg); + ctx.GetSTDIN().assign(optarg); + ctx.GetSTDOUT().assign(optarg); + ctx.GetSTDERR().assign(optarg); break; case 'I': - stdin_path.assign(optarg); + ctx.GetSTDIN().assign(optarg); break; case 'O': - stdout_path.assign(optarg); + ctx.GetSTDOUT().assign(optarg); break; case 'E': - stderr_path.assign(optarg); + ctx.GetSTDERR().assign(optarg); break; case 'n': @@ -910,11 +927,7 @@ main (int argc, char *argv[]) if (arch_name.empty()) { -#if defined (__i386__) - arch_name.assign ("i386"); -#elif defined (__x86_64__) - arch_name.assign ("x86_64"); -#elif defined (__arm__) +#if defined (__arm__) arch_name.assign ("arm"); #endif } @@ -923,24 +936,15 @@ main (int argc, char *argv[]) DNBSetArchitecture (arch_name.c_str()); } - if (arch_name.empty()) - { - fprintf(stderr, "error: no architecture was specified\n"); - exit (8); - } +// if (arch_name.empty()) +// { +// fprintf(stderr, "error: no architecture was specified\n"); +// exit (8); +// } // Skip any options we consumed with getopt_long argc -= optind; argv += optind; - g_remoteSP.reset (new RNBRemote (use_native_registers, arch_name.c_str())); - - - RNBRemote *remote = g_remoteSP.get(); - if (remote == NULL) - { - RNBLogSTDERR ("error: failed to create a remote connection class\n"); - return -1; - } if (!working_dir.empty()) { @@ -953,9 +957,6 @@ main (int argc, char *argv[]) remote->Initialize(); - RNBContext& ctx = remote->Context(); - - // It is ok for us to set NULL as the logfile (this will disable any logging) if (log_file != NULL) @@ -1250,9 +1251,9 @@ main (int argc, char *argv[]) case eRNBRunLoopModeInferiorLaunching: { mode = RNBRunLoopLaunchInferior (remote, - stdin_path.empty() ? NULL : stdin_path.c_str(), - stdout_path.empty() ? NULL : stdout_path.c_str(), - stderr_path.empty() ? NULL : stderr_path.c_str(), + ctx.GetSTDINPath(), + ctx.GetSTDOUTPath(), + ctx.GetSTDERRPath(), no_stdio); if (mode == eRNBRunLoopModeInferiorExecuting)