Skip to content

Commit eb5ac23

Browse files
authored
Merge pull request #4091 from apple/🍒/austria/53e9ee3027db+10222764a9a3+14bd14f9f92f+453f8c87ff20
🍒/austria/53e9ee3027db+10222764a9a3+14bd14f9f92f+453f8c87ff20
2 parents dbb9a0c + 1172d84 commit eb5ac23

File tree

9 files changed

+83
-144
lines changed

9 files changed

+83
-144
lines changed

lldb/lldb/test/API/functionalities/gdb_remote_client/TestPlatformMacOSX.py

Lines changed: 0 additions & 60 deletions
This file was deleted.

lldb/lldb/unittests/Platform/PlatformMacOSXTest.cpp

Lines changed: 0 additions & 52 deletions
This file was deleted.

lldb/source/Target/Process.cpp

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4485,6 +4485,12 @@ class IOHandlerProcessSTDIO : public IOHandler {
44854485

44864486
~IOHandlerProcessSTDIO() override = default;
44874487

4488+
void SetIsRunning(bool running) {
4489+
std::lock_guard<std::mutex> guard(m_mutex);
4490+
SetIsDone(!running);
4491+
m_is_running = running;
4492+
}
4493+
44884494
// Each IOHandler gets to run until it is done. It should read data from the
44894495
// "in" and place output into "out" and "err and return when done.
44904496
void Run() override {
@@ -4504,49 +4510,52 @@ class IOHandlerProcessSTDIO : public IOHandler {
45044510
// FD_ZERO, FD_SET are not supported on windows
45054511
#ifndef _WIN32
45064512
const int pipe_read_fd = m_pipe.GetReadFileDescriptor();
4507-
m_is_running = true;
4508-
while (!GetIsDone()) {
4513+
SetIsRunning(true);
4514+
while (true) {
4515+
{
4516+
std::lock_guard<std::mutex> guard(m_mutex);
4517+
if (GetIsDone())
4518+
break;
4519+
}
4520+
45094521
SelectHelper select_helper;
45104522
select_helper.FDSetRead(read_fd);
45114523
select_helper.FDSetRead(pipe_read_fd);
45124524
Status error = select_helper.Select();
45134525

4514-
if (error.Fail()) {
4515-
SetIsDone(true);
4516-
} else {
4517-
char ch = 0;
4518-
size_t n;
4519-
if (select_helper.FDIsSetRead(read_fd)) {
4520-
n = 1;
4521-
if (m_read_file.Read(&ch, n).Success() && n == 1) {
4522-
if (m_write_file.Write(&ch, n).Fail() || n != 1)
4523-
SetIsDone(true);
4524-
} else
4525-
SetIsDone(true);
4526-
}
4527-
if (select_helper.FDIsSetRead(pipe_read_fd)) {
4528-
size_t bytes_read;
4529-
// Consume the interrupt byte
4530-
Status error = m_pipe.Read(&ch, 1, bytes_read);
4531-
if (error.Success()) {
4532-
switch (ch) {
4533-
case 'q':
4534-
SetIsDone(true);
4535-
break;
4536-
case 'i':
4537-
if (StateIsRunningState(m_process->GetState()))
4538-
m_process->SendAsyncInterrupt();
4539-
break;
4540-
}
4541-
}
4526+
if (error.Fail())
4527+
break;
4528+
4529+
char ch = 0;
4530+
size_t n;
4531+
if (select_helper.FDIsSetRead(read_fd)) {
4532+
n = 1;
4533+
if (m_read_file.Read(&ch, n).Success() && n == 1) {
4534+
if (m_write_file.Write(&ch, n).Fail() || n != 1)
4535+
break;
4536+
} else
4537+
break;
4538+
}
4539+
4540+
if (select_helper.FDIsSetRead(pipe_read_fd)) {
4541+
size_t bytes_read;
4542+
// Consume the interrupt byte
4543+
Status error = m_pipe.Read(&ch, 1, bytes_read);
4544+
if (error.Success()) {
4545+
if (ch == 'q')
4546+
break;
4547+
if (ch == 'i')
4548+
if (StateIsRunningState(m_process->GetState()))
4549+
m_process->SendAsyncInterrupt();
45424550
}
45434551
}
45444552
}
4545-
m_is_running = false;
4553+
SetIsRunning(false);
45464554
#endif
45474555
}
45484556

45494557
void Cancel() override {
4558+
std::lock_guard<std::mutex> guard(m_mutex);
45504559
SetIsDone(true);
45514560
// Only write to our pipe to cancel if we are in
45524561
// IOHandlerProcessSTDIO::Run(). We can end up with a python command that
@@ -4603,7 +4612,8 @@ class IOHandlerProcessSTDIO : public IOHandler {
46034612
NativeFile m_write_file; // Write to this file (usually the master pty for
46044613
// getting io to debuggee)
46054614
Pipe m_pipe;
4606-
std::atomic<bool> m_is_running{false};
4615+
std::mutex m_mutex;
4616+
bool m_is_running = false;
46074617
};
46084618

46094619
void Process::SetSTDIOFileDescriptor(int fd) {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test.lldbpexpect import PExpectTest
5+
6+
class TestIOHandlerProcessSTDIO(PExpectTest):
7+
8+
mydir = TestBase.compute_mydir(__file__)
9+
NO_DEBUG_INFO_TESTCASE = True
10+
11+
# PExpect uses many timeouts internally and doesn't play well
12+
# under ASAN on a loaded machine..
13+
@skipIfAsan
14+
def test(self):
15+
self.build()
16+
self.launch(executable=self.getBuildArtifact("a.out"))
17+
self.child.sendline("run")
18+
19+
self.child.send("foo\n")
20+
self.child.expect_exact("stdout: foo")
21+
22+
self.child.send("bar\n")
23+
self.child.expect_exact("stdout: bar")
24+
25+
self.child.send("baz\n")
26+
self.child.expect_exact("stdout: baz")
27+
28+
self.child.sendcontrol('d')
29+
self.expect_prompt()
30+
self.quit()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
int main(int argc, char **argv) {
5+
for (std::string line; std::getline(std::cin, line);)
6+
std::cout << "stdout: " << line << '\n';
7+
return 0;
8+
}

0 commit comments

Comments
 (0)