forked from OSchip/llvm-project
[lldb/test] Add ability to specify environment when spawning processes
We only had that ability for regular debugger launches. This meant that it was not possible to use the normal dlopen patterns in attach tests. This fixes that.
This commit is contained in:
parent
156cb4cc64
commit
9413ead7bc
|
@ -360,7 +360,7 @@ class _BaseProcess(object):
|
|||
"""Returns process PID if has been launched already."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def launch(self, executable, args):
|
||||
def launch(self, executable, args, extra_env):
|
||||
"""Launches new process with given executable and args."""
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@ -379,13 +379,19 @@ class _LocalProcess(_BaseProcess):
|
|||
def pid(self):
|
||||
return self._proc.pid
|
||||
|
||||
def launch(self, executable, args):
|
||||
def launch(self, executable, args, extra_env):
|
||||
env=None
|
||||
if extra_env:
|
||||
env = dict(os.environ)
|
||||
env.update([kv.split("=", 1) for kv in extra_env])
|
||||
|
||||
self._proc = Popen(
|
||||
[executable] + args,
|
||||
stdout=open(
|
||||
os.devnull) if not self._trace_on else None,
|
||||
stdin=PIPE,
|
||||
preexec_fn=lldbplatformutil.enable_attach)
|
||||
preexec_fn=lldbplatformutil.enable_attach,
|
||||
env=env)
|
||||
|
||||
def terminate(self):
|
||||
if self._proc.poll() is None:
|
||||
|
@ -424,7 +430,7 @@ class _RemoteProcess(_BaseProcess):
|
|||
def pid(self):
|
||||
return self._pid
|
||||
|
||||
def launch(self, executable, args):
|
||||
def launch(self, executable, args, extra_env):
|
||||
if self._install_remote:
|
||||
src_path = executable
|
||||
dst_path = lldbutil.join_remote_paths(
|
||||
|
@ -450,6 +456,9 @@ class _RemoteProcess(_BaseProcess):
|
|||
launch_info.AddSuppressFileAction(1, False, True)
|
||||
launch_info.AddSuppressFileAction(2, False, True)
|
||||
|
||||
if extra_env:
|
||||
launch_info.SetEnvironmentEntries(extra_env, True)
|
||||
|
||||
err = lldb.remote_platform.Launch(launch_info)
|
||||
if err.Fail():
|
||||
raise Exception(
|
||||
|
@ -952,13 +961,13 @@ class Base(unittest2.TestCase):
|
|||
del p
|
||||
del self.subprocesses[:]
|
||||
|
||||
def spawnSubprocess(self, executable, args=[], install_remote=True):
|
||||
def spawnSubprocess(self, executable, args=[], extra_env=None, install_remote=True):
|
||||
""" Creates a subprocess.Popen object with the specified executable and arguments,
|
||||
saves it in self.subprocesses, and returns the object.
|
||||
"""
|
||||
proc = _RemoteProcess(
|
||||
install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
|
||||
proc.launch(executable, args)
|
||||
proc.launch(executable, args, extra_env=extra_env)
|
||||
self.subprocesses.append(proc)
|
||||
return proc
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ from lldbsuite.test import lldbutil
|
|||
class TestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
NO_DEBUG_INFO_TESTCASE = True
|
||||
|
||||
@skipIfRemote
|
||||
def test_load_after_attach(self):
|
||||
|
@ -17,18 +18,19 @@ class TestCase(TestBase):
|
|||
exe = self.getBuildArtifact("a.out")
|
||||
lib = self.getBuildArtifact(lib_name)
|
||||
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
environment = self.registerSharedLibrariesWithTarget(target, ["lib_b"])
|
||||
|
||||
# Spawn a new process.
|
||||
# use realpath to workaround llvm.org/pr48376
|
||||
# Pass path to solib for dlopen to properly locate the library.
|
||||
popen = self.spawnSubprocess(os.path.realpath(exe), args = [os.path.realpath(lib)])
|
||||
pid = popen.pid
|
||||
popen = self.spawnSubprocess(os.path.realpath(exe), extra_env=environment)
|
||||
|
||||
# Attach to the spawned process.
|
||||
self.runCmd("process attach -p " + str(pid))
|
||||
|
||||
target = self.dbg.GetSelectedTarget()
|
||||
process = target.GetProcess()
|
||||
self.assertTrue(process, PROCESS_IS_VALID)
|
||||
error = lldb.SBError()
|
||||
process = target.AttachToProcessWithID(self.dbg.GetListener(),
|
||||
popen.pid, error)
|
||||
self.assertSuccess(error)
|
||||
|
||||
# Continue until first breakpoint.
|
||||
breakpoint1 = self.target().BreakpointCreateBySourceRegex(
|
||||
|
|
|
@ -1,30 +1,10 @@
|
|||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "dylib.h"
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
// We do not use the dylib.h implementation, because
|
||||
// we need to pass full path to the dylib.
|
||||
void* dylib_open(const char* full_path) {
|
||||
#ifdef _WIN32
|
||||
return LoadLibraryA(full_path);
|
||||
#else
|
||||
return dlopen(full_path, RTLD_LAZY);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
assert(argc == 2 && "argv[1] must be the full path to lib_b library");
|
||||
const char* dylib_full_path= argv[1];
|
||||
printf("Using dylib at: %s\n", dylib_full_path);
|
||||
|
||||
// Wait until debugger is attached.
|
||||
int main_thread_continue = 0;
|
||||
int i = 0;
|
||||
|
@ -38,7 +18,7 @@ int main(int argc, char* argv[]) {
|
|||
assert(i != timeout && "timed out waiting for debugger");
|
||||
|
||||
// dlopen the 'liblib_b.so' shared library.
|
||||
void* dylib_handle = dylib_open(dylib_full_path);
|
||||
void* dylib_handle = dylib_open("lib_b");
|
||||
assert(dylib_handle && "dlopen failed");
|
||||
|
||||
return i; // break after dlopen
|
||||
|
|
Loading…
Reference in New Issue