Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b64ab3f

Browse files
committedDec 22, 2017
debugserver: Propagate environment in launch-mode (pr35671)
Summary: Make sure we propagate environment when starting debugserver with a pre-loaded inferior. AFAIK, RNBRunLoopLaunchInferior is only called in pre-loaded inferior scenario, so we can just pick up the debugserver environment instead of trying to construct an envp from the (empty) context. This makes debugserver pass an test added for an equivalent lldb-server fix. Reviewers: jasonmolenda, clayborg Subscribers: JDevlieghere, lldb-commits Differential Revision: https://reviews.llvm.org/D41352 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@321355 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d2c07f3 commit b64ab3f

File tree

7 files changed

+77
-22
lines changed

7 files changed

+77
-22
lines changed
 

‎tools/debugserver/source/RNBContext.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ const char *RNBContext::EnvironmentAtIndex(size_t index) {
4242
return NULL;
4343
}
4444

45+
static std::string GetEnvironmentKey(const std::string &env) {
46+
std::string key = env.substr(0, env.find('='));
47+
if (!key.empty() && key.back() == '=')
48+
key.pop_back();
49+
return key;
50+
}
51+
52+
void RNBContext::PushEnvironmentIfNeeded(const char *arg) {
53+
if (!arg)
54+
return;
55+
std::string arg_key = GetEnvironmentKey(arg);
56+
57+
for (const std::string &entry: m_env_vec) {
58+
if (arg_key == GetEnvironmentKey(entry))
59+
return;
60+
}
61+
m_env_vec.push_back(arg);
62+
}
63+
4564
const char *RNBContext::ArgumentAtIndex(size_t index) {
4665
if (index < m_arg_vec.size())
4766
return m_arg_vec[index].c_str();

‎tools/debugserver/source/RNBContext.h

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class RNBContext {
8686
if (arg)
8787
m_env_vec.push_back(arg);
8888
}
89+
void PushEnvironmentIfNeeded(const char *arg);
8990
void ClearEnvironment() {
9091
m_env_vec.erase(m_env_vec.begin(), m_env_vec.end());
9192
}

‎tools/debugserver/source/debugserver.cpp

+14-8
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,7 @@ int main(int argc, char *argv[]) {
10201020
optind = 1;
10211021
#endif
10221022

1023+
bool forward_env = false;
10231024
while ((ch = getopt_long_only(argc, argv, short_options, g_long_options,
10241025
&long_option_index)) != -1) {
10251026
DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", ch, (uint8_t)ch,
@@ -1251,14 +1252,7 @@ int main(int argc, char *argv[]) {
12511252
break;
12521253

12531254
case 'F':
1254-
// Pass the current environment down to the process that gets launched
1255-
{
1256-
char **host_env = *_NSGetEnviron();
1257-
char *env_entry;
1258-
size_t i;
1259-
for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
1260-
remote->Context().PushEnvironment(env_entry);
1261-
}
1255+
forward_env = true;
12621256
break;
12631257

12641258
case '2':
@@ -1420,6 +1414,18 @@ int main(int argc, char *argv[]) {
14201414
if (start_mode == eRNBRunLoopModeExit)
14211415
return -1;
14221416

1417+
if (forward_env || start_mode == eRNBRunLoopModeInferiorLaunching) {
1418+
// Pass the current environment down to the process that gets launched
1419+
// This happens automatically in the "launching" mode. For the rest, we
1420+
// only do that if the user explicitly requested this via --forward-env
1421+
// argument.
1422+
char **host_env = *_NSGetEnviron();
1423+
char *env_entry;
1424+
size_t i;
1425+
for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
1426+
remote->Context().PushEnvironmentIfNeeded(env_entry);
1427+
}
1428+
14231429
RNBRunLoopMode mode = start_mode;
14241430
char err_str[1024] = {'\0'};
14251431

‎unittests/tools/lldb-server/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ add_lldb_test_executable(thread_inferior inferior/thread_inferior.cpp)
1313
add_lldb_test_executable(environment_check inferior/environment_check.cpp)
1414

1515
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
16-
add_definitions(-DLLDB_SERVER="$<TARGET_FILE:debugserver>")
16+
add_definitions(-DLLDB_SERVER="$<TARGET_FILE:debugserver>" -DLLDB_SERVER_IS_DEBUGSERVER=1)
1717
else()
18-
add_definitions(-DLLDB_SERVER="$<TARGET_FILE:lldb-server>")
18+
add_definitions(-DLLDB_SERVER="$<TARGET_FILE:lldb-server>" -DLLDB_SERVER_IS_DEBUGSERVER=0)
1919
endif()
2020

2121
add_definitions(

‎unittests/tools/lldb-server/tests/LLGSTest.cpp

+17-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ using namespace lldb_private;
1616
using namespace llvm;
1717

1818
TEST_F(TestBase, LaunchModePreservesEnvironment) {
19-
if (TestClient::IsDebugServer()) {
20-
GTEST_LOG_(WARNING) << "Test fails with debugserver: llvm.org/pr35671";
21-
return;
22-
}
23-
2419
putenv(const_cast<char *>("LLDB_TEST_MAGIC_VARIABLE=LLDB_TEST_MAGIC_VALUE"));
2520

2621
auto ClientOr = TestClient::launch(getLogFileName(),
@@ -34,3 +29,20 @@ TEST_F(TestBase, LaunchModePreservesEnvironment) {
3429
HasValue(testing::Property(&StopReply::getKind,
3530
WaitStatus{WaitStatus::Exit, 0})));
3631
}
32+
33+
TEST_F(TestBase, DS_TEST(DebugserverEnv)) {
34+
// Test that --env takes precedence over inherited environment variables.
35+
putenv(const_cast<char *>("LLDB_TEST_MAGIC_VARIABLE=foobar"));
36+
37+
auto ClientOr = TestClient::launchCustom(getLogFileName(),
38+
{ "--env", "LLDB_TEST_MAGIC_VARIABLE=LLDB_TEST_MAGIC_VALUE" },
39+
{getInferiorPath("environment_check")});
40+
ASSERT_THAT_EXPECTED(ClientOr, Succeeded());
41+
auto &Client = **ClientOr;
42+
43+
ASSERT_THAT_ERROR(Client.ContinueAll(), Succeeded());
44+
ASSERT_THAT_EXPECTED(
45+
Client.GetLatestStopReplyAs<StopReplyExit>(),
46+
HasValue(testing::Property(&StopReply::getKind,
47+
WaitStatus{WaitStatus::Exit, 0})));
48+
}

‎unittests/tools/lldb-server/tests/TestClient.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@ using namespace lldb_private;
2727
using namespace llvm;
2828

2929
namespace llgs_tests {
30-
bool TestClient::IsDebugServer() {
31-
return sys::path::filename(LLDB_SERVER).contains("debugserver");
32-
}
33-
34-
bool TestClient::IsLldbServer() { return !IsDebugServer(); }
3530

3631
TestClient::TestClient(std::unique_ptr<Connection> Conn) {
3732
SetConnection(Conn.release());
@@ -56,6 +51,10 @@ Expected<std::unique_ptr<TestClient>> TestClient::launch(StringRef Log) {
5651
}
5752

5853
Expected<std::unique_ptr<TestClient>> TestClient::launch(StringRef Log, ArrayRef<StringRef> InferiorArgs) {
54+
return launchCustom(Log, {}, InferiorArgs);
55+
}
56+
57+
Expected<std::unique_ptr<TestClient>> TestClient::launchCustom(StringRef Log, ArrayRef<StringRef> ServerArgs, ArrayRef<StringRef> InferiorArgs) {
5958
const ArchSpec &arch_spec = HostInfo::GetArchitecture();
6059
Args args;
6160
args.AppendArgument(LLDB_SERVER);
@@ -80,6 +79,9 @@ Expected<std::unique_ptr<TestClient>> TestClient::launch(StringRef Log, ArrayRef
8079
args.AppendArgument(
8180
("localhost:" + Twine(listen_socket.GetLocalPortNumber())).str());
8281

82+
for (StringRef arg : ServerArgs)
83+
args.AppendArgument(arg);
84+
8385
if (!InferiorArgs.empty()) {
8486
args.AppendArgument("--");
8587
for (StringRef arg : InferiorArgs)

‎unittests/tools/lldb-server/tests/TestClient.h

+17-2
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,20 @@
2121
#include <memory>
2222
#include <string>
2323

24+
#if LLDB_SERVER_IS_DEBUGSERVER
25+
#define LLGS_TEST(x) DISABLED_ ## x
26+
#define DS_TEST(x) x
27+
#else
28+
#define LLGS_TEST(x) x
29+
#define DS_TEST(x) DISABLED_ ## x
30+
#endif
31+
2432
namespace llgs_tests {
2533
class TestClient
2634
: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient {
2735
public:
28-
static bool IsDebugServer();
29-
static bool IsLldbServer();
36+
static bool IsDebugServer() { return LLDB_SERVER_IS_DEBUGSERVER; }
37+
static bool IsLldbServer() { return !IsDebugServer(); }
3038

3139
/// Launches the server, connects it to the client and returns the client. If
3240
/// Log is non-empty, the server will write it's log to this file.
@@ -37,6 +45,13 @@ class TestClient
3745
static llvm::Expected<std::unique_ptr<TestClient>>
3846
launch(llvm::StringRef Log, llvm::ArrayRef<llvm::StringRef> InferiorArgs);
3947

48+
/// Allows user to pass additional arguments to the server. Be careful when
49+
/// using this for generic tests, as the two stubs have different
50+
/// command-line interfaces.
51+
static llvm::Expected<std::unique_ptr<TestClient>>
52+
launchCustom(llvm::StringRef Log, llvm::ArrayRef<llvm::StringRef> ServerArgs, llvm::ArrayRef<llvm::StringRef> InferiorArgs);
53+
54+
4055
~TestClient() override;
4156
llvm::Error SetInferior(llvm::ArrayRef<std::string> inferior_args);
4257
llvm::Error ListThreadsInStopReply();

0 commit comments

Comments
 (0)