31 : args(args), log(log), gdb_state(
gdb_statet::NOT_CREATED)
80 if(
pipe(pipe_input) == -1)
85 if(
pipe(pipe_output) == -1)
100 close(pipe_input[1]);
101 close(pipe_output[0]);
107 dprintf(pipe_output[1],
"binary name: %s\n",
args.front().c_str());
112 exec_cmd.push_back(
"--interpreter=mi");
117 sizeof(
char *) * (
exec_cmd.size() + 1)));
123 sizeof(
char) * (
exec_cmd[
i].length() + 1)));
127 dprintf(pipe_output[1],
"Loading gdb...\n");
133 dprintf(pipe_output[1],
"(gdb) \n");
139 close(pipe_input[0]);
140 close(pipe_output[1]);
176 std::string line(command);
218 "EOF must have been reached when the error indicator on the stream "
219 "is not set and fgets returned NULL");
221 result.empty() || result.back() !=
'\n',
222 "when EOF is reached then either no characters were read or the string"
223 " read does not end in a newline");
228 std::string chunk(
buf);
229 INVARIANT(!chunk.empty(),
"chunk cannot be empty when EOF was not reached");
232 }
while(result.back() !=
'\n');
246 }
while(line !=
"(gdb) \n");
266 std::string record =
strip_string(line.substr(line.find(
',') + 1));
282 const std::string command =
"core " +
corefile;
318 if(
frame_content.find(
"func=\"malloc\"") != std::string::npos)
342 std::string command(
"-break-insert");
383 const auto it = record.find(
"reason");
386 const std::string &reason = it->second;
388 if(reason ==
"breakpoint-hit")
393 else if(reason ==
"exited-normally")
400 "gdb stopped for unhandled reason `" + reason +
"`");
413 "could not create variable for expression `" + expr +
"`");
422 const auto it = record.find(
"value");
425 const std::string value = it->second;
428 value.back() !=
'"' ||
429 (value.length() >= 2 && value[value.length() - 2] ==
'\\'),
430 "quotes should have been stripped off from value");
431 INVARIANT(value.back() !=
'\n',
"value should not end in a newline");
459 const std::string
string = result[4];
463 const std::size_t len =
string.length();
467 "pointer-string should be: backslash, quotes, .., backslash, quotes");
470 "pointer-string should be: backslash, quotes, .., backslash, quotes");
473 "pointer-string should be: backslash, quotes, .., backslash, quotes");
475 string[len - 2] ==
'\\',
476 "pointer-string should be: backslash, quotes, .., backslash, quotes");
478 string[len - 1] ==
'"',
479 "pointer-string should be: backslash, quotes, .., backslash, quotes");
504 std::regex
regex(R
"([^ ]+ '([^']+)')");
511 return std::string{result[1]};
526 std::size_t depth = 0;
527 std::string::size_type
start = 0;
529 const std::string::size_type
n = s.length();
531 for(std::string::size_type
i = 0;
i <
n;
i++)
535 if(
c ==
'{' ||
c ==
'[')
539 else if(
c ==
'}' ||
c ==
']')
544 if(depth == 0 && (
c ==
',' ||
i ==
n - 1))
546 const std::string
item =
550 std::string::size_type
j =
item.find(
'=');
558 const char first = value.front();
559 const char last = value.back();
561 INVARIANT(first ==
'"' || first ==
'{' || first ==
'[',
"");
569 value = value.substr(1, value.length() - 2);
572 auto r = result.insert(std::make_pair(
key, value));
595 return R
"((?:)" + regex + R"()?)";
610 const auto value = it->second;
613 value.back() !=
'"' ||
614 (value.length() >= 2 && value[value.length() - 2] ==
'\\'),
615 "quotes should have been stripped off from value");
616 INVARIANT(value.back() !=
'\n',
"value should not end in a newline");
626 if(it->second !=
"breakpoint-hit")
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
bool was_command_accepted()
optionalt< std::string > get_value(const std::string &expr)
Get the memory address pointed to by the given pointer expression.
void check_command_accepted()
bool run_gdb_to_breakpoint(const std::string &breakpoint)
Run gdb to the given breakpoint.
void collect_malloc_calls()
Intercepts the gdb-analysis at the malloc call-site to add the corresponding information into allocat...
static std::string r_or(const std::string ®ex_left, const std::string ®ex_right)
void create_gdb_process()
Create a new gdb process for analysing the binary indicated by the first element in args
std::map< std::string, size_t > allocated_memory
track the allocated size for each malloc call maps hexadecimal address to the number of bytes
const std::string r_hex_addr
void write_to_gdb(const std::string &command)
std::map< std::string, std::string > gdb_output_recordt
void run_gdb_from_core(const std::string &corefile)
Run gdb with the given core file.
const commandst & get_command_log()
Return the vector of commands that have been written to gdb so far.
static std::string r_opt(const std::string ®ex)
std::string eval_expr(const std::string &expr)
std::string read_next_line()
const std::string r_string
std::forward_list< std::string > commandst
std::string get_register_value(const gdb_output_recordt &record)
Parse the record produced by listing register value.
gdb_output_recordt get_most_recent_record(const std::string &tag, const bool must_exist=false)
const std::string malloc_name
std::string get_value_from_record(const gdb_output_recordt &record, const std::string &value_name)
Locate and return the value for a given name.
static gdb_output_recordt parse_gdb_output_record(const std::string &s)
std::vector< std::string > args
size_t query_malloc_size(const std::string &pointer_expr)
Get the exact allocated size for a pointer pointer_expr.
gdb_apit(const std::vector< std::string > &args, const bool log=false)
Create a gdb_apit object.
std::string read_most_recent_line()
pointer_valuet get_memory(const std::string &expr)
Get the value of a pointer associated with expr.
bool most_recent_line_has_tag(const std::string &tag)
~gdb_apit()
Terminate the gdb process and close open streams (for reading from and writing to gdb)
bool hit_malloc_breakpoint(const gdb_output_recordt &stopped_record)
Check if the breakpoint we hit is inside a malloc.
bool has_prefix(const std::string &s, const std::string &prefix)
Low-level interface to gdb.
#define CHECK_RETURN(CONDITION)
#define UNREACHABLE
This should be used to mark dead code.
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
std::size_t safe_string2size_t(const std::string &str, int base)
std::string strip_string(const std::string &s)
Remove all whitespace characters from either end of a string.
Data associated with the value of a pointer, i.e.