[lldb/test] Ensure launched processes are ready to be attached

Linux systems can be configured (and most of them are configured that
way) to disable attaching to unrelated processes, /unless/ those
processes explicitly allow that.

Our test inferiors do that by explicitly calling prctl(PR_SET_PTRACER,
PR_SET_PTRACER_ANY) (a.k.a., lldb_enable_attach). This requires
additional synchronization to ensure that the test does not attempt
attach before that statement is executed.

This is working fine (albeit cumbersome) for most tests but
TestGdbRemoteAttachWait is special in that it wants to start the
inferior _after_ issuing the attach request. This means that the usual
synchronization method does not work.

This patch introduces a different solution -- enable attaching in the
test harness, before the process is launched. Besides fixing this
problem, this is also better because it avoids the need to add special
code to each attach test (which is a common error).

One gotcha here is that it won't work for remote test suites, as we
don't control launching there. However, we could add a similar option to
lldb-platform, or require that lldb-platform itself is started with
attaching enabled. At that point we could delete all lldb_enable_attach
logic.
This commit is contained in:
Pavel Labath 2021-01-14 11:53:53 +01:00
parent 8f1d7f3753
commit a997a1d7fb
2 changed files with 15 additions and 2 deletions

View file

@ -4,11 +4,12 @@ architecture and/or the platform dependent nature of the tests. """
from __future__ import absolute_import
# System modules
import ctypes
import itertools
import os
import re
import subprocess
import sys
import os
# Third-party modules
import six
@ -198,3 +199,14 @@ def hasChattyStderr(test_case):
if match_android_device(test_case.getArchitecture(), ['aarch64'], range(22, 25+1)):
return True # The dynamic linker on the device will complain about unknown DT entries
return False
if getHostPlatform() == "linux":
def enable_attach():
"""Enable attaching to _this_ process, if host requires such an action.
Suitable for use as a preexec_fn in subprocess.Popen and similar."""
c = ctypes.CDLL(None)
PR_SET_PTRACER = ctypes.c_int(0x59616d61)
PR_SET_PTRACER_ANY = ctypes.c_ulong(-1)
c.prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY)
else:
enable_attach = None

View file

@ -384,7 +384,8 @@ class _LocalProcess(_BaseProcess):
[executable] + args,
stdout=open(
os.devnull) if not self._trace_on else None,
stdin=PIPE)
stdin=PIPE,
preexec_fn=lldbplatformutil.enable_attach)
def terminate(self):
if self._proc.poll() is None: