Skip to content

Commit b7abfc4

Browse files
committed
memory analyzer: fail when gdb cannot be started
When gdb wasn't available, the forked child would not terminate and the parent would wait forever. Also make the unit tests less fragile by not relying on a particular directory that they are being run from. Test files had to be loaded from a specific location; instead, place them in the source code and generate temporary files at runtime.
1 parent ac11ec8 commit b7abfc4

File tree

4 files changed

+90
-51
lines changed

4 files changed

+90
-51
lines changed

src/memory-analyzer/gdb_api.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,13 @@ void gdb_apit::create_gdb_process()
132132

133133
// Only reachable, if execvp failed
134134
int errno_value = errno;
135-
dprintf(pipe_output[1], "errno in child: %s\n", strerror(errno_value));
135+
dprintf(pipe_output[1], "Starting gdb failed: %s\n", strerror(errno_value));
136+
dprintf(pipe_output[1], "(gdb) \n");
137+
throw gdb_interaction_exceptiont("could not run gdb");
136138
}
137139
else
138140
{
139141
// parent process
140-
gdb_state = gdb_statet::CREATED;
141-
142142
close(pipe_input[0]);
143143
close(pipe_output[1]);
144144

@@ -149,6 +149,11 @@ void gdb_apit::create_gdb_process()
149149
command_stream = fdopen(pipe_input[1], "w");
150150

151151
std::string line = read_most_recent_line();
152+
if(has_prefix(line, "Starting gdb failed:"))
153+
throw gdb_interaction_exceptiont(line);
154+
155+
gdb_state = gdb_statet::CREATED;
156+
152157
CHECK_RETURN(
153158
has_prefix(line, R"(~"done)") ||
154159
has_prefix(line, R"(~"Reading)"));

unit/memory-analyzer/gdb_api.cpp

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,61 @@ Author: Malte Mues <[email protected]>
1818
#include <iostream>
1919

2020
#include <memory-analyzer/gdb_api.cpp>
21+
2122
#include <util/run.h>
23+
#include <util/tempfile.h>
2224

23-
void compile_test_file()
25+
struct compile_test_filet
2426
{
25-
REQUIRE(
26-
run("gcc", {"gcc", "-g", "-o", "test", "memory-analyzer/test.c"}) == 0);
27-
}
27+
compile_test_filet() : compiled("test", "")
28+
{
29+
temporary_filet tmp("test", ".c");
30+
std::ofstream of(tmp().c_str());
31+
REQUIRE(of.is_open());
32+
33+
of << "int x;\n"
34+
"float y;\n"
35+
"char z;\n"
36+
"\n"
37+
"char *s = \"abc\";\n"
38+
"int *p;\n"
39+
"void *vp;\n"
40+
"int *np = 0;\n"
41+
"void *vp_string;\n"
42+
"\n"
43+
"void checkpoint()\n"
44+
"{\n"
45+
"}\n"
46+
"void checkpoint2()\n"
47+
"{\n"
48+
"}\n"
49+
"\n"
50+
"void func()\n"
51+
"{\n"
52+
" checkpoint2();\n"
53+
"}\n"
54+
"\n"
55+
"int main()\n"
56+
"{\n"
57+
" x = 8;\n"
58+
" y = 2.5;\n"
59+
" z = 'c';\n"
60+
"\n"
61+
" p = &x;\n"
62+
" vp = (void *)&x;\n"
63+
" vp_string = s;\n"
64+
"\n"
65+
" checkpoint();\n"
66+
"\n"
67+
" return 0;\n"
68+
"}\n";
69+
of.close();
70+
71+
REQUIRE(run("gcc", {"gcc", "-g", "-o", compiled(), tmp()}) == 0);
72+
}
73+
74+
temporary_filet compiled;
75+
};
2876

2977
void check_for_gdb()
3078
{
@@ -46,10 +94,10 @@ class gdb_api_testt : public gdb_apit
4694
void gdb_api_internals_test()
4795
{
4896
check_for_gdb();
49-
compile_test_file();
97+
compile_test_filet test_file;
5098

5199
std::vector<std::string> args;
52-
args.push_back("test");
100+
args.push_back(test_file.compiled());
53101

54102
SECTION("parse gdb output record")
55103
{
@@ -67,9 +115,34 @@ void gdb_api_internals_test()
67115

68116
SECTION("read a line from an input stream")
69117
{
118+
temporary_filet tmp("input", ".txt");
119+
std::ofstream of(tmp().c_str());
120+
REQUIRE(of.is_open());
121+
122+
of << "abc\n"
123+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
124+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
125+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
126+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
127+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
128+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
129+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
130+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
131+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
132+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
133+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
134+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
135+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
136+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
137+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
138+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
139+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
140+
"xyz";
141+
of.close();
142+
70143
gdb_api_testt gdb_api(args);
71144

72-
FILE *f = fopen("memory-analyzer/input.txt", "r");
145+
FILE *f = fopen(tmp().c_str(), "r");
73146
gdb_api.response_stream = f;
74147

75148
std::string line = gdb_api.read_next_line();
@@ -102,10 +175,10 @@ TEST_CASE("gdb api internals test", "[core][memory-analyzer]")
102175
TEST_CASE("gdb api test", "[core][memory-analyzer]")
103176
{
104177
check_for_gdb();
105-
compile_test_file();
178+
compile_test_filet test_file;
106179

107180
std::vector<std::string> args;
108-
args.push_back("test");
181+
args.push_back(test_file.compiled());
109182

110183
{
111184
gdb_apit gdb_api(args, true);

unit/memory-analyzer/input.txt

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

unit/memory-analyzer/test.c

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

0 commit comments

Comments
 (0)