Skip to content

Commit b5754c4

Browse files
committed
Use streams to communicate with gdb subprocess
This switches gdb_apit to use streams to communicate with the gdb subprocess instead of using pipes/file descriptors directly.
1 parent 5c48449 commit b5754c4

File tree

2 files changed

+40
-36
lines changed

2 files changed

+40
-36
lines changed

src/memory-analyzer/gdb_api.cpp

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@
1313

1414
gdb_apit::gdb_apit(const char *arg) : binary_name(arg)
1515
{
16-
memset(buffer, 0, MAX_READ_SIZE_GDB_BUFFER);
1716
}
1817

1918
int gdb_apit::create_gdb_process()
2019
{
20+
pid_t gdb_process;
21+
22+
int pipe_input[2];
23+
int pipe_output[2];
24+
2125
if(pipe(pipe_input) == -1)
2226
{
2327
throw gdb_interaction_exceptiont("could not create pipe for stdin!");
@@ -56,55 +60,60 @@ int gdb_apit::create_gdb_process()
5660
// parent process
5761
close(pipe_input[0]);
5862
close(pipe_output[1]);
63+
64+
// get stream for reading the gdb output
65+
input_stream = fdopen(pipe_output[0], "r");
66+
67+
// get stream for writing to gdb
68+
output_stream = fdopen(pipe_input[1], "w");
69+
5970
write_to_gdb("set max-value-size unlimited\n");
6071
}
6172
return 0;
6273
}
6374

6475
void gdb_apit::terminate_gdb_process()
6576
{
66-
close(pipe_input[0]);
67-
close(pipe_input[1]);
77+
fclose(input_stream);
78+
fclose(output_stream);
6879
}
6980

7081
void gdb_apit::write_to_gdb(const std::string &command)
7182
{
72-
if(
73-
write(pipe_input[1], command.c_str(), command.length()) !=
74-
(ssize_t)command.length())
83+
if(fputs(command.c_str(), output_stream) == EOF)
7584
{
7685
throw gdb_interaction_exceptiont("Could not write a command to gdb");
7786
}
7887
}
7988

8089
std::string gdb_apit::read_next_line()
8190
{
82-
char token;
83-
std::string line;
91+
std::string result;
92+
8493
do
8594
{
86-
while(buffer_position >= last_read_size)
95+
const size_t buf_size = 1024;
96+
char buf[buf_size];
97+
98+
const char *c = fgets(buf, buf_size, input_stream);
99+
100+
if(c == NULL)
87101
{
88-
read_next_buffer_chunc();
102+
if(ferror(input_stream))
103+
{
104+
throw gdb_interaction_exceptiont("error reading from gdb");
105+
}
106+
107+
INVARIANT(feof(input_stream), "");
108+
INVARIANT(result.back() != '\n', "");
109+
110+
return result;
89111
}
90-
token = buffer[buffer_position];
91-
line += token;
92-
++buffer_position;
93-
} while(token != '\n');
94-
return line;
95-
}
96112

97-
void gdb_apit::read_next_buffer_chunc()
98-
{
99-
memset(buffer, 0, last_read_size);
100-
const auto read_size =
101-
read(pipe_output[0], &buffer, MAX_READ_SIZE_GDB_BUFFER);
102-
if(read_size < 0)
103-
{
104-
throw gdb_interaction_exceptiont("Error reading from gdb_process");
105-
}
106-
last_read_size = read_size;
107-
buffer_position = 0;
113+
result += std::string(buf);
114+
} while(result.back() != '\n');
115+
116+
return result;
108117
}
109118

110119
void gdb_apit::run_gdb_from_core(const std::string &corefile)

src/memory-analyzer/gdb_api.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
#include <exception>
88

9+
#include <util/exception_utils.h>
10+
911
class gdb_apit
1012
{
1113
public:
@@ -21,21 +23,14 @@ class gdb_apit
2123
std::string get_memory(const std::string &variable);
2224

2325
private:
24-
static const int MAX_READ_SIZE_GDB_BUFFER = 600;
25-
2626
const char *binary_name;
27-
char buffer[MAX_READ_SIZE_GDB_BUFFER];
28-
int buffer_position;
29-
pid_t gdb_process;
30-
int last_read_size;
31-
int pipe_input[2];
32-
int pipe_output[2];
27+
FILE *input_stream;
28+
FILE *output_stream;
3329

3430
static std::string create_command(const std::string &variable);
3531
void write_to_gdb(const std::string &command);
3632

3733
std::string read_next_line();
38-
void read_next_buffer_chunc();
3934

4035
static bool check_for_gdb_breakpoint_error(const std::string &line);
4136
static bool check_for_gdb_core_error(const std::string &line);

0 commit comments

Comments
 (0)