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; _______________________________________________ lldb-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
