[Lldb-commits] [lldb] r212873 - llgs: implement --setsid.
Todd Fiala
todd.fiala at gmail.com
Fri Jul 11 18:12:44 PDT 2014
Author: tfiala
Date: Fri Jul 11 20:12:44 2014
New Revision: 212873
URL: http://llvm.org/viewvc/llvm-project?rev=212873&view=rev
Log:
llgs: implement --setsid.
The --setsid (-S) option changes the session id for the lldb-gdbserver process.
This is used by tools such as lldb-platform and allows the user to prevent
llgs from being in the same session as a calling terminal session.
This will prevents terminal group control signals from affecting
lldb-gdbserver.
See also:
https://github.com/tfiala/lldb/issues/38
Added:
lldb/trunk/test/tools/lldb-gdbserver/commandline/
lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubNamedPipe.py
- copied, changed from r212863, lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py
lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubSetSID.py
Removed:
lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py
Modified:
lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp
Removed: lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py?rev=212872&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py (original)
+++ lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py (removed)
@@ -1,87 +0,0 @@
-import unittest2
-
-import gdbremote_testcase
-import os
-import os.path
-import select
-import tempfile
-import time
-from lldbtest import *
-
-class TestStubNamedPipe(gdbremote_testcase.GdbRemoteTestCaseBase):
- def create_named_pipe(self):
- temp_dir = tempfile.mkdtemp()
- named_pipe_path = os.path.join(temp_dir, "stub_port_number")
- try:
- os.mkfifo(named_pipe_path)
- except OSError, e:
- # print "Failed to create named pipe: %s" % e
- raise e
- return named_pipe_path
-
- def get_port_from_named_pipe(self):
- # Set port to 0
- self.port = 0
-
- # Don't turn on any kind of logging
- self.debug_monitor_extra_args = ""
-
- # Create the named pipe that we're reading on.
- self.named_pipe_path = self.create_named_pipe()
- self.assertIsNotNone(self.named_pipe_path)
- # print "using named pipe:{}".format(self.named_pipe_path)
- try:
- # print "launching server..."
- server = self.launch_debug_monitor()
- # print "server launched..."
- self.assertIsNotNone(server)
- self.assertTrue(server.isalive())
- server.expect("(debugserver|lldb-gdbserver)", timeout=10)
-
- # print "about to open named pipe..."
- # Open the read side of the pipe in non-blocking mode. This will return right away, ready or not.
- fd = os.open(self.named_pipe_path, os.O_RDONLY | os.O_NONBLOCK)
- named_pipe = os.fdopen(fd, "r")
- self.assertIsNotNone(named_pipe)
-
- # print "waiting on content from the named pipe..."
- # Wait for something to read with a max timeout.
- (ready_readers, _, _) = select.select([fd], [], [], 5)
- self.assertIsNotNone(ready_readers, "write side of pipe has not written anything - stub isn't writing to pipe.")
- self.assertNotEqual(len(ready_readers), 0, "write side of pipe has not written anything - stub isn't writing to pipe.")
-
- try:
- # Read the port from the named pipe.
- stub_port_raw = named_pipe.read()
- self.assertIsNotNone(stub_port_raw)
- self.assertNotEqual(len(stub_port_raw), 0, "no content to read on pipe")
-
- # Trim null byte, convert to int.
- stub_port_raw = stub_port_raw[:-1]
- stub_port = int(stub_port_raw)
- self.assertTrue(stub_port > 0)
- finally:
- named_pipe.close()
- # print "stub is listening on port: {} (from text '{}')".format(stub_port, stub_port_raw)
- finally:
- temp_dir = os.path.dirname(self.named_pipe_path)
- try:
- os.remove(self.named_pipe_path)
- except:
- # Not required.
- None
- os.rmdir(temp_dir)
-
- @debugserver_test
- def test_get_port_from_named_pipe_debugserver(self):
- self.init_debugserver_test()
- self.set_inferior_startup_launch()
- self.get_port_from_named_pipe()
-
- @llgs_test
- @dwarf_test
- # @unittest2.expectedFailure()
- def test_get_port_from_named_pipe_llgs(self):
- self.init_llgs_test()
- self.set_inferior_startup_launch()
- self.get_port_from_named_pipe()
Copied: lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubNamedPipe.py (from r212863, lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubNamedPipe.py?p2=lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubNamedPipe.py&p1=lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py&r1=212863&r2=212873&rev=212873&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-gdbserver/TestStubNamedPipe.py (original)
+++ lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubNamedPipe.py Fri Jul 11 20:12:44 2014
@@ -1,14 +1,19 @@
import unittest2
+# Add the directory above ours to the python library path since we
+# will import from there.
+import os.path
+import sys
+sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
+
import gdbremote_testcase
import os
-import os.path
import select
import tempfile
import time
from lldbtest import *
-class TestStubNamedPipe(gdbremote_testcase.GdbRemoteTestCaseBase):
+class TestStubNamedPipeTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
def create_named_pipe(self):
temp_dir = tempfile.mkdtemp()
named_pipe_path = os.path.join(temp_dir, "stub_port_number")
@@ -79,8 +84,6 @@ class TestStubNamedPipe(gdbremote_testca
self.get_port_from_named_pipe()
@llgs_test
- @dwarf_test
- # @unittest2.expectedFailure()
def test_get_port_from_named_pipe_llgs(self):
self.init_llgs_test()
self.set_inferior_startup_launch()
Added: lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubSetSID.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubSetSID.py?rev=212873&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubSetSID.py (added)
+++ lldb/trunk/test/tools/lldb-gdbserver/commandline/TestStubSetSID.py Fri Jul 11 20:12:44 2014
@@ -0,0 +1,80 @@
+import unittest2
+
+# Add the directory above ours to the python library path since we
+# will import from there.
+import os.path
+import sys
+sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
+
+import gdbremote_testcase
+import os
+import select
+import tempfile
+import time
+from lldbtest import *
+
+class TestStubSetSIDTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):
+ def get_stub_sid(self, extra_stub_args=None):
+ # Launch debugserver
+ if extra_stub_args:
+ self.debug_monitor_extra_args = extra_stub_args
+ else:
+ self.debug_monitor_extra_args = ""
+
+ server = self.launch_debug_monitor()
+ self.assertIsNotNone(server)
+ self.assertTrue(server.isalive())
+ server.expect("(debugserver|lldb-gdbserver)", timeout=10)
+
+ # Get the process id for the stub.
+ return os.getsid(server.pid)
+
+ def sid_is_same_without_setsid(self):
+ stub_sid = self.get_stub_sid()
+ self.assertEquals(stub_sid, os.getsid(0))
+
+ def sid_is_different_with_setsid(self):
+ stub_sid = self.get_stub_sid(" --setsid")
+ self.assertNotEquals(stub_sid, os.getsid(0))
+
+ def sid_is_different_with_S(self):
+ stub_sid = self.get_stub_sid(" -S")
+ self.assertNotEquals(stub_sid, os.getsid(0))
+
+ @debugserver_test
+ @unittest2.expectedFailure() # This is the whole purpose of this feature, I would expect it to be the same without --setsid. Investigate.
+ def test_sid_is_same_without_setsid_debugserver(self):
+ self.init_debugserver_test()
+ self.set_inferior_startup_launch()
+ self.sid_is_same_without_setsid()
+
+ @llgs_test
+ @unittest2.expectedFailure() # This is the whole purpose of this feature, I would expect it to be the same without --setsid. Investigate.
+ def test_sid_is_same_without_setsid_llgs(self):
+ self.init_llgs_test()
+ self.set_inferior_startup_launch()
+ self.sid_is_same_without_setsid()
+
+ @debugserver_test
+ def test_sid_is_different_with_setsid_debugserver(self):
+ self.init_debugserver_test()
+ self.set_inferior_startup_launch()
+ self.sid_is_different_with_setsid()
+
+ @llgs_test
+ def test_sid_is_different_with_setsid_llgs(self):
+ self.init_llgs_test()
+ self.set_inferior_startup_launch()
+ self.sid_is_different_with_setsid()
+
+ @debugserver_test
+ def test_sid_is_different_with_S_debugserver(self):
+ self.init_debugserver_test()
+ self.set_inferior_startup_launch()
+ self.sid_is_different_with_S()
+
+ @llgs_test
+ def test_sid_is_different_with_S_llgs(self):
+ self.init_llgs_test()
+ self.set_inferior_startup_launch()
+ self.sid_is_different_with_S()
Modified: lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp?rev=212873&r1=212872&r2=212873&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp (original)
+++ lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp Fri Jul 11 20:12:44 2014
@@ -17,6 +17,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
// C++ Includes
@@ -71,6 +74,7 @@ static struct option g_long_options[] =
{ "log-flags", required_argument, NULL, 'f' },
{ "attach", required_argument, NULL, 'a' },
{ "named-pipe", required_argument, NULL, 'P' },
+ { "setsid", no_argument, NULL, 'S' }, // Call setsid() to make llgs run in its own session.
{ NULL, 0, NULL, 0 }
};
@@ -540,6 +544,30 @@ main (int argc, char *argv[])
named_pipe_path = optarg;
break;
+#ifndef _WIN32
+ case 'S':
+ // Put llgs into a new session. Terminals group processes
+ // into sessions and when a special terminal key sequences
+ // (like control+c) are typed they can cause signals to go out to
+ // all processes in a session. Using this --setsid (-S) option
+ // will cause debugserver to run in its own sessions and be free
+ // from such issues.
+ //
+ // This is useful when llgs is spawned from a command
+ // line application that uses llgs to do the debugging,
+ // yet that application doesn't want llgs receiving the
+ // signals sent to the session (i.e. dying when anyone hits ^C).
+ {
+ const ::pid_t new_sid = setsid();
+ if (new_sid == -1)
+ {
+ const char *errno_str = strerror(errno);
+ fprintf (stderr, "failed to set new session id for %s (%s)\n", LLGS_PROGRAM_NAME, errno_str ? errno_str : "<no error string>");
+ }
+ }
+ break;
+#endif
+
case 'a': // attach {pid|process_name}
if (optarg && optarg[0])
attach_target = optarg;
More information about the lldb-commits
mailing list