CBMC
gdb_api.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: GDB Machine Interface API
4 
5 Author: Malte Mues <mail.mues@gmail.com>
6  Daniel Poetzl
7 
8 \*******************************************************************/
9 
17 
18 #ifndef CPROVER_MEMORY_ANALYZER_GDB_API_H
19 #define CPROVER_MEMORY_ANALYZER_GDB_API_H
20 #include <unistd.h>
21 
22 #include <algorithm>
23 #include <exception>
24 #include <forward_list>
25 #include <map>
26 
27 #include <util/exception_utils.h>
28 
30 class gdb_apit
31 {
32 public:
33  using commandst = std::forward_list<std::string>;
34 
38  {
40  std::string address_string;
42  {
43  }
44  explicit memory_addresst(const std::string &address_string)
46  {
47  }
48 
49  bool is_null() const
50  {
51  return null_address;
52  }
53  bool operator<(const memory_addresst &other) const
54  {
55  return address_string < other.address_string;
56  }
57  std::string string() const
58  {
59  return address_string;
60  }
61  };
62 
68  explicit gdb_apit(
69  const std::vector<std::string> &args, const bool log = false);
70 
73  ~gdb_apit();
74 
78  {
80  const std::string &address = "",
81  const std::string &pointee = "",
82  const std::string &character = "",
83  const optionalt<std::string> &string = {},
84  const bool valid = false)
85  : address(address),
88  string(string),
89  valid(valid)
90  {
91  }
92 
94  std::string pointee;
95  std::string character;
97 
98  bool has_known_offset() const
99  {
100  return std::any_of(
101  pointee.begin(), pointee.end(), [](char c) { return c == '+'; });
102  }
103 
104  bool valid;
105  };
106 
111  size_t query_malloc_size(const std::string &pointer_expr);
112 
115  void create_gdb_process();
116 
121  bool run_gdb_to_breakpoint(const std::string &breakpoint);
122 
125  void run_gdb_from_core(const std::string &corefile);
126 
131  optionalt<std::string> get_value(const std::string &expr);
132 
136  pointer_valuet get_memory(const std::string &expr);
137 
140  const commandst &get_command_log();
141 
142 protected:
143  // arguments passed to gdb, first argument is the command to execute
144  std::vector<std::string> args;
145 
148 
149  const bool log;
151 
152  enum class gdb_statet
153  {
154  NOT_CREATED,
155  CREATED,
156  STOPPED // valid state, reached e.g. after breakpoint was hit
157  };
158 
160 
163  std::map<std::string, size_t> allocated_memory;
164 
165  typedef std::map<std::string, std::string> gdb_output_recordt;
166  static gdb_output_recordt parse_gdb_output_record(const std::string &s);
167 
168  void write_to_gdb(const std::string &command);
169 
170  std::string read_next_line();
171  std::string read_most_recent_line();
172 
173  std::string eval_expr(const std::string &expr);
174 
176  get_most_recent_record(const std::string &tag, const bool must_exist = false);
177 
178  bool most_recent_line_has_tag(const std::string &tag);
179  bool was_command_accepted();
180  void check_command_accepted();
181 
184  void collect_malloc_calls();
185 
190  std::string get_value_from_record(
191  const gdb_output_recordt &record,
192  const std::string &value_name);
193 
197  bool hit_malloc_breakpoint(const gdb_output_recordt &stopped_record);
198 
202  std::string get_register_value(const gdb_output_recordt &record);
203 
204  static std::string r_opt(const std::string &regex);
205 
206  static std::string
207  r_or(const std::string &regex_left, const std::string &regex_right);
208 
209  // regex group for hex memory address (part of the output of gdb when printing
210  // a pointer), matches e.g. 0x601040 and extracts 0x601040
211  const std::string r_hex_addr = R"((0x(?:0|[1-9a-f][0-9a-f]*)))";
212 
213  // regex group for identifier (optional part of the output of gdb when
214  // printing a pointer), matches e.g. <abc> and extracts abc
215  const std::string r_id = R"(<([^<>]+)>)";
216 
217  // regex group for octal encoded char (optional part of the output of gdb when
218  // printing a pointer), matches e.g. \"\\003\" and extracts \\003
219  const std::string r_char = R"(\\"(\\\\[0-7]{3})\\")";
220 
221  // regex group for string (optional part of the output of gdb when printing a
222  // pointer), matches e.g. \"abc\" and extracts \"abc\"
223  const std::string r_string = R"((\\".*\\"))";
224 
225  // name of malloc function
226  const std::string malloc_name = "malloc";
227 };
228 
230 {
231 public:
232  explicit gdb_interaction_exceptiont(std::string reason)
233  : cprover_exception_baset(std::move(reason))
234  {
235  }
236 };
237 
238 #endif // CPROVER_MEMORY_ANALYZER_GDB_API_H
gdb_apit::r_or
static std::string r_or(const std::string &regex_left, const std::string &regex_right)
exception_utils.h
gdb_apit::hit_malloc_breakpoint
bool hit_malloc_breakpoint(const gdb_output_recordt &stopped_record)
Check if the breakpoint we hit is inside a malloc.
gdb_apit::collect_malloc_calls
void collect_malloc_calls()
Intercepts the gdb-analysis at the malloc call-site to add the corresponding information into allocat...
Definition: gdb_api.cpp:290
gdb_apit::r_opt
static std::string r_opt(const std::string &regex)
gdb_apit::query_malloc_size
size_t query_malloc_size(const std::string &pointer_expr)
Get the exact allocated size for a pointer pointer_expr.
Definition: gdb_api.cpp:58
gdb_interaction_exceptiont
Definition: gdb_api.h:229
gdb_apit::pointer_valuet
Data associated with the value of a pointer, i.e.
Definition: gdb_api.h:77
gdb_apit::args
std::vector< std::string > args
Definition: gdb_api.h:144
gdb_apit::pointer_valuet::character
std::string character
Definition: gdb_api.h:95
gdb_apit::gdb_statet::NOT_CREATED
@ NOT_CREATED
gdb_apit::commandst
std::forward_list< std::string > commandst
Definition: gdb_api.h:33
gdb_apit::get_memory
pointer_valuet get_memory(const std::string &expr)
Get the value of a pointer associated with expr.
gdb_apit::parse_gdb_output_record
static gdb_output_recordt parse_gdb_output_record(const std::string &s)
gdb_apit::most_recent_line_has_tag
bool most_recent_line_has_tag(const std::string &tag)
Definition: gdb_api.cpp:271
gdb_apit::pointer_valuet::pointee
std::string pointee
Definition: gdb_api.h:94
gdb_apit::gdb_state
gdb_statet gdb_state
Definition: gdb_api.h:159
gdb_apit::gdb_apit
gdb_apit(const std::vector< std::string > &args, const bool log=false)
Create a gdb_apit object.
Definition: gdb_api.cpp:30
gdb_apit::command_stream
FILE * command_stream
Definition: gdb_api.h:147
gdb_apit::eval_expr
std::string eval_expr(const std::string &expr)
Definition: gdb_api.cpp:406
gdb_apit::memory_addresst
Memory address imbued with the explicit boolean data indicating if the address is null or not.
Definition: gdb_api.h:37
gdb_apit
Interface for running and querying GDB.
Definition: gdb_api.h:30
gdb_apit::command_log
commandst command_log
Definition: gdb_api.h:150
gdb_apit::memory_addresst::address_string
std::string address_string
Definition: gdb_api.h:40
gdb_apit::gdb_statet::STOPPED
@ STOPPED
gdb_apit::memory_addresst::operator<
bool operator<(const memory_addresst &other) const
Definition: gdb_api.h:53
gdb_apit::r_hex_addr
const std::string r_hex_addr
Definition: gdb_api.h:211
gdb_apit::memory_addresst::memory_addresst
memory_addresst(const std::string &address_string)
Definition: gdb_api.h:44
gdb_apit::response_stream
FILE * response_stream
Definition: gdb_api.h:146
gdb_apit::memory_addresst::memory_addresst
memory_addresst()
Definition: gdb_api.h:41
gdb_apit::get_most_recent_record
gdb_output_recordt get_most_recent_record(const std::string &tag, const bool must_exist=false)
Definition: gdb_api.cpp:252
gdb_apit::memory_addresst::null_address
bool null_address
Definition: gdb_api.h:39
gdb_apit::write_to_gdb
void write_to_gdb(const std::string &command)
Definition: gdb_api.cpp:171
gdb_apit::~gdb_apit
~gdb_apit()
Terminate the gdb process and close open streams (for reading from and writing to gdb)
Definition: gdb_api.cpp:35
gdb_apit::read_next_line
std::string read_next_line()
Definition: gdb_api.cpp:198
gdb_apit::get_command_log
const commandst & get_command_log()
Return the vector of commands that have been written to gdb so far.
Definition: gdb_api.cpp:192
gdb_apit::pointer_valuet::valid
bool valid
Definition: gdb_api.h:104
gdb_apit::pointer_valuet::string
optionalt< std::string > string
Definition: gdb_api.h:96
gdb_apit::pointer_valuet::pointer_valuet
pointer_valuet(const std::string &address="", const std::string &pointee="", const std::string &character="", const optionalt< std::string > &string={}, const bool valid=false)
Definition: gdb_api.h:79
gdb_apit::malloc_name
const std::string malloc_name
Definition: gdb_api.h:226
gdb_apit::allocated_memory
std::map< std::string, size_t > allocated_memory
track the allocated size for each malloc call maps hexadecimal address to the number of bytes
Definition: gdb_api.h:163
gdb_apit::r_id
const std::string r_id
Definition: gdb_api.h:215
gdb_apit::get_value
optionalt< std::string > get_value(const std::string &expr)
Get the memory address pointed to by the given pointer expression.
gdb_apit::get_register_value
std::string get_register_value(const gdb_output_recordt &record)
Parse the record produced by listing register value.
gdb_apit::log
const bool log
Definition: gdb_api.h:149
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
gdb_apit::was_command_accepted
bool was_command_accepted()
gdb_interaction_exceptiont::gdb_interaction_exceptiont
gdb_interaction_exceptiont(std::string reason)
Definition: gdb_api.h:232
gdb_apit::get_value_from_record
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.
gdb_apit::create_gdb_process
void create_gdb_process()
Create a new gdb process for analysing the binary indicated by the first element in args
Definition: gdb_api.cpp:69
gdb_apit::r_string
const std::string r_string
Definition: gdb_api.h:223
gdb_apit::pointer_valuet::address
memory_addresst address
Definition: gdb_api.h:93
gdb_apit::check_command_accepted
void check_command_accepted()
gdb_apit::gdb_statet
gdb_statet
Definition: gdb_api.h:152
gdb_apit::run_gdb_to_breakpoint
bool run_gdb_to_breakpoint(const std::string &breakpoint)
Run gdb to the given breakpoint.
Definition: gdb_api.cpp:335
gdb_apit::memory_addresst::string
std::string string() const
Definition: gdb_api.h:57
gdb_apit::run_gdb_from_core
void run_gdb_from_core(const std::string &corefile)
Run gdb with the given core file.
Definition: gdb_api.cpp:277
gdb_apit::r_char
const std::string r_char
Definition: gdb_api.h:219
gdb_apit::memory_addresst::is_null
bool is_null() const
Definition: gdb_api.h:49
gdb_apit::gdb_statet::CREATED
@ CREATED
cprover_exception_baset::reason
std::string reason
The reason this exception was generated.
Definition: exception_utils.h:44
cprover_exception_baset
Base class for exceptions thrown in the cprover project.
Definition: exception_utils.h:24
gdb_apit::read_most_recent_line
std::string read_most_recent_line()
Definition: gdb_api.cpp:237
gdb_apit::gdb_output_recordt
std::map< std::string, std::string > gdb_output_recordt
Definition: gdb_api.h:165
gdb_apit::pointer_valuet::has_known_offset
bool has_known_offset() const
Definition: gdb_api.h:98