summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py49
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp3
-rw-r--r--lldb/scripts/Python/python-typemaps.swig50
-rw-r--r--lldb/source/Host/windows/ProcessLauncherWindows.cpp35
4 files changed, 94 insertions, 43 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py b/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
index 3131000be42..0eeb6ff9379 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/TestProcessLaunch.py
@@ -4,12 +4,15 @@ Test lldb process launch flags.
from __future__ import print_function
+import copy
+import os
+import time
-
-import os, time
import lldb
from lldbsuite.test.lldbtest import *
+import six
+
class ProcessLaunchTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@@ -17,9 +20,18 @@ class ProcessLaunchTestCase(TestBase):
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
+ self.stdout_redirect_file = 'lldb-stdout-redirect.txt'
# disable "There is a running process, kill it and restart?" prompt
self.runCmd("settings set auto-confirm true")
- self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+ def tearDown(self):
+ self.runCmd("settings clear auto-confirm")
+
+ try:
+ os.unlink(self.stdout_redirect_file)
+ except:
+ pass
+
+ super().tearDown()
@not_remote_testsuite_ready
def test_io (self):
@@ -180,8 +192,9 @@ class ProcessLaunchTestCase(TestBase):
self.fail(err_msg)
def test_environment_with_special_char (self):
- """Test that environment variables containing '*' and '}' are communicated correctly to the lldb-server."""
- d = {'CXX_SOURCES' : 'print_env.cpp'}
+ """Test that environment variables containing '*' and '}' are handled correctly by the inferior."""
+ source = 'print_env.cpp'
+ d = {'CXX_SOURCES' : source}
self.build(dictionary=d)
self.setTearDownCleanup(d)
exe = os.path.join (os.getcwd(), "a.out")
@@ -189,19 +202,19 @@ class ProcessLaunchTestCase(TestBase):
evil_var = 'INIT*MIDDLE}TAIL'
target = self.dbg.CreateTarget(exe)
- process = target.LaunchSimple(None, ['EVIL=' + evil_var], self.get_process_working_directory())
- self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
-
- out = process.GetSTDOUT(len(evil_var))
- self.assertIsNotNone(out, "Encountered an error reading the process's output")
+ main_source_spec = lldb.SBFileSpec(source)
+ breakpoint = target.BreakpointCreateBySourceRegex('// Set breakpoint here.', main_source_spec)
- out = out[:len(evil_var)]
- if out != evil_var:
- self.fail('The environment variable was mis-coded: %s\n' % repr(out))
+ process = target.LaunchSimple(None, ['EVIL=' + evil_var], self.get_process_working_directory())
+ self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
- newline = process.GetSTDOUT(1)
- self.assertIsNotNone(newline, "Encountered an error reading the process's output")
+ threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
+ self.assertEqual(len(threads), 1)
+ frame = threads[0].GetFrameAtIndex(0)
+ sbvalue = frame.EvaluateExpression("evil")
+ value = sbvalue.GetSummary().strip('"')
- newline = newline[0]
- if newline != '\r' and newline != '\n':
- self.fail('Garbage at end of environment variable')
+ self.assertEqual(value, evil_var)
+ process.Continue()
+ self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
+ pass \ No newline at end of file
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
index cbb9b217591..8c6df8ea01a 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/process_launch/print_env.cpp
@@ -5,7 +5,6 @@
int main (int argc, char **argv)
{
char *evil = getenv("EVIL");
- puts(evil);
- return 0;
+ return 0; // Set breakpoint here.
}
diff --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig
index 68e442defd3..ca918198863 100644
--- a/lldb/scripts/Python/python-typemaps.swig
+++ b/lldb/scripts/Python/python-typemaps.swig
@@ -1,20 +1,22 @@
/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */
%typemap(in) char ** {
+ using namespace lldb_private;
/* Check if is a list */
- if (PyList_Check($input)) {
- int size = PyList_Size($input);
+ if (PythonList::Check($input)) {
+ PythonList list(PyRefType::Borrowed, $input);
+ int size = list.GetSize();
int i = 0;
- $1 = (char **) malloc((size+1) * sizeof(char*));
+ $1 = (char**)malloc((size+1)*sizeof(char*));
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
- if (PyString_Check(o))
- $1[i] = PyString_AsString(o);
- else {
+ PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();
+ if (!py_str.IsAllocated()) {
PyErr_SetString(PyExc_TypeError,"list must contain strings");
free($1);
- return NULL;
+ return nullptr;
}
+
+ $1[i] = const_cast<char*>(py_str.GetString().data());
}
$1[i] = 0;
} else if ($input == Py_None) {
@@ -42,12 +44,14 @@
%typemap(typecheck) char ** {
/* Check if is a list */
$1 = 1;
- if (PyList_Check($input)) {
- int size = PyList_Size($input);
+ using namespace lldb_private;
+ if (PythonList::Check($input)) {
+ PythonList list(PyRefType::Borrowed, $input);
+ int size = list.GetSize();
int i = 0;
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
- if (!PyString_Check(o)) { $1 = 0; }
+ PythonString s = list.GetItemAtIndex(i).AsType<PythonString>();
+ if (!s.IsAllocated()) { $1 = 0; }
}
}
else
@@ -81,13 +85,12 @@
$1 = (char**)malloc((size+1)*sizeof(char*));
for (int i = 0; i < size; i++) {
- PythonObject o = py_list.GetItemAtIndex(i);
- if (!PythonString::Check(o.get())) {
+ auto py_str = py_list.GetItemAtIndex(i).AsType<PythonString>();
+ if (!py_str.IsAllocated()) {
PyErr_SetString(PyExc_TypeError,"list must contain strings");
free($1);
return nullptr;
}
- auto py_str = o.AsType<PythonString>();
$1[i] = const_cast<char*>(py_str.GetString().data());
}
@@ -101,14 +104,16 @@
}
%typemap(typecheck) char const ** {
+ using namespace lldb_private;
/* Check if is a list */
$1 = 1;
- if (PyList_Check($input)) {
- int size = PyList_Size($input);
+ if (PythonList::Check($input)) {
+ PythonList list(PyRefType::Borrowed, $input);
+ int size = list.GetSize();
int i = 0;
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
- if (!PyString_Check(o)) { $1 = 0; }
+ PythonString s = list.GetItemAtIndex(i).AsType<PythonString>();
+ if (!s.IsAllocated()) { $1 = 0; }
}
}
else
@@ -126,10 +131,13 @@
int i;
len = 0;
while ($1[len]) len++;
- $result = PyList_New(len);
+ using namespace lldb_private;
+ PythonList list(len);
for (i = 0; i < len; i++) {
- PyList_SetItem($result, i, PyString_FromString($1[i]));
+ PythonString str($1[i]);
+ list.SetItemAtIndex(i, str);
}
+ $result = list.release();
}
/* Typemap definitions to allow SWIG to properly handle char buffer. */
diff --git a/lldb/source/Host/windows/ProcessLauncherWindows.cpp b/lldb/source/Host/windows/ProcessLauncherWindows.cpp
index 355dd40544f..a99faa227f7 100644
--- a/lldb/source/Host/windows/ProcessLauncherWindows.cpp
+++ b/lldb/source/Host/windows/ProcessLauncherWindows.cpp
@@ -17,6 +17,31 @@
using namespace lldb;
using namespace lldb_private;
+namespace
+{
+void
+CreateEnvironmentBuffer(const Args &env, std::vector<char> &buffer)
+{
+ if (env.GetArgumentCount() == 0)
+ return;
+
+ int bytes = 0;
+ for (int i = 0; i < env.GetArgumentCount(); ++i)
+ bytes += strlen(env.GetArgumentAtIndex(i)) + sizeof(char);
+ bytes += sizeof(char);
+ buffer.resize(bytes);
+ char *cur_entry = &buffer[0];
+ for (int i = 0; i < env.GetArgumentCount(); ++i)
+ {
+ ::strcpy(cur_entry, env.GetArgumentAtIndex(i));
+ cur_entry += strlen(cur_entry) + sizeof(char);
+ }
+ // Environment buffer is a null terminated list of null terminated
+ // strings, so it is terminated by two null bytes.
+ buffer.back() = 0;
+}
+}
+
HostProcess
ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
{
@@ -49,10 +74,16 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, Erro
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
flags |= DEBUG_ONLY_THIS_PROCESS;
+ auto &env = const_cast<Args &>(launch_info.GetEnvironmentEntries());
+ LPVOID env_block = nullptr;
+ ::CreateEnvironmentBuffer(env, environment);
+ if (!environment.empty())
+ env_block = environment.data();
+
executable = launch_info.GetExecutableFile().GetPath();
launch_info.GetArguments().GetQuotedCommandString(commandLine);
- BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags, NULL,
- launch_info.GetWorkingDirectory().GetCString(), &startupinfo, &pi);
+ BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags,
+ env_block, launch_info.GetWorkingDirectory().GetCString(), &startupinfo, &pi);
if (result)
{
// Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.
OpenPOWER on IntegriCloud