Skip to content

Commit 3b88fa5

Browse files
committed
Update memory analyzer driver and options parsing
1 parent 9794b8f commit 3b88fa5

File tree

3 files changed

+178
-66
lines changed

3 files changed

+178
-66
lines changed
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
// Copyright 2018 Author: Malte Mues <[email protected]>
2-
#ifdef __linux__
2+
3+
// clang-format off
4+
#if defined(__linux__) || \
5+
defined(__FreeBSD_kernel__) || \
6+
defined(__GNU__) || \
7+
defined(__unix__) || \
8+
defined(__CYGWIN__) || \
9+
defined(__MACH__)
10+
// clang-format on
311

412
#include "memory_analyzer_parse_options.h"
513

@@ -8,9 +16,12 @@ int main(int argc, const char **argv)
816
memory_analyzer_parse_optionst parse_options(argc, argv);
917
return parse_options.main();
1018
}
19+
1120
#else
21+
1222
int main()
1323
{
14-
throw "only supported on Linux platforms currently\n";
24+
throw "the memory analyzer is only supported on Unices\n";
1525
}
26+
1627
#endif
Lines changed: 135 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,188 @@
1-
// Copyright 2018 Author: Malte Mues <[email protected]>
1+
/*******************************************************************\
2+
3+
Module: Memory Analyzer
4+
5+
Author: Malte Mues <[email protected]>
6+
Daniel Poetzl
7+
8+
\*******************************************************************/
29

310
/// \file
411
/// Commandline parser for the memory analyzer executing main work.
512

6-
#ifdef __linux__
13+
// clang-format off
14+
#if defined(__linux__) || \
15+
defined(__FreeBSD_kernel__) || \
16+
defined(__GNU__) || \
17+
defined(__unix__) || \
18+
defined(__CYGWIN__) || \
19+
defined(__MACH__)
20+
// clang-format on
721

822
#include "memory_analyzer_parse_options.h"
923
#include "analyze_symbol.h"
1024
#include "gdb_api.h"
1125

26+
#include <fstream>
27+
28+
#include <ansi-c/ansi_c_language.h>
29+
1230
#include <goto-programs/goto_model.h>
1331
#include <goto-programs/read_goto_binary.h>
32+
#include <goto-programs/show_symbol_table.h>
33+
34+
#include <langapi/mode.h>
35+
1436
#include <util/config.h>
1537
#include <util/exit_codes.h>
1638
#include <util/message.h>
1739
#include <util/string_utils.h>
40+
#include <util/version.h>
41+
42+
memory_analyzer_parse_optionst::memory_analyzer_parse_optionst(
43+
int argc,
44+
const char *argv[])
45+
: parse_options_baset(
46+
MEMORY_ANALYZER_OPTIONS,
47+
argc,
48+
argv,
49+
ui_message_handler),
50+
ui_message_handler(cmdline, std::string("MEMORY-ANALYZER ") + CBMC_VERSION),
51+
message(ui_message_handler)
52+
{
53+
}
1854

1955
int memory_analyzer_parse_optionst::doit()
2056
{
21-
// This script is the entry point and has to make sure
22-
// that the config object is set to a valid architecture.
23-
// config is later used to determine right size for types.
24-
// If config is not set, you might see a bunch of types with
25-
// size 0.
26-
// It might be desierable to convert this into flags in the future.
27-
config.ansi_c.mode = configt::ansi_ct::flavourt::GCC;
28-
config.ansi_c.set_arch_spec_x86_64();
57+
if(cmdline.isset("version"))
58+
{
59+
message.status() << CBMC_VERSION << '\n';
60+
return CPROVER_EXIT_SUCCESS;
61+
}
62+
63+
config.set(cmdline);
2964

3065
if(cmdline.args.size() != 1)
3166
{
32-
error() << "Please provide one binary with symbols to process" << eom;
33-
return CPROVER_EXIT_USAGE_ERROR;
67+
throw invalid_command_line_argument_exceptiont(
68+
"no binary provided for analysis", "<binary>");
69+
}
70+
71+
if(!cmdline.isset("symbols"))
72+
{
73+
throw invalid_command_line_argument_exceptiont(
74+
"need to provide symbols to analyse via --symbols", "--symbols");
75+
}
76+
77+
const bool core_file = cmdline.isset("core-file");
78+
const bool breakpoint = cmdline.isset("breakpoint");
79+
80+
if(!(core_file ^ breakpoint))
81+
{
82+
throw invalid_command_line_argument_exceptiont(
83+
"need to provide either option --core-file or option --breakpoint", "");
84+
}
85+
86+
const bool output_file = cmdline.isset("output-file");
87+
const bool symtab_snapshot = cmdline.isset("symtab-snapshot");
88+
89+
if(symtab_snapshot && output_file)
90+
{
91+
throw invalid_command_line_argument_exceptiont(
92+
"printing to a file is not supported for symbol table snapshot output",
93+
"--symtab-snapshot");
3494
}
3595

36-
std::string binary = cmdline.args[0];
96+
register_language(new_ansi_c_language);
3797

38-
gdb_apit gdb_api = gdb_apit(binary.c_str());
98+
std::string binary = cmdline.args.front();
99+
100+
gdb_apit gdb_api(binary.c_str());
39101
gdb_api.create_gdb_process();
40102

41-
if(cmdline.isset("core-file"))
103+
if(core_file)
42104
{
43105
std::string core_file = cmdline.get_value("core-file");
44106
gdb_api.run_gdb_from_core(core_file);
45107
}
46-
else if(cmdline.isset("breakpoint"))
108+
else if(breakpoint)
47109
{
48110
std::string breakpoint = cmdline.get_value("breakpoint");
49111
gdb_api.run_gdb_to_breakpoint(breakpoint);
50112
}
51-
else
52-
{
53-
error() << "Either the 'core-file' or 'breakpoint; flag must be provided\n"
54-
<< "Cannot execute memory-analyzer. Going to shut it down...\n"
55-
<< messaget::eom;
56113

57-
gdb_api.terminate_gdb_process();
114+
const std::string symbol_list(cmdline.get_value("symbols"));
115+
std::vector<std::string> result;
116+
split_string(symbol_list, ',', result, true, true);
58117

59-
help();
60-
return CPROVER_EXIT_USAGE_ERROR;
61-
}
118+
auto opt = read_goto_binary(binary, ui_message_handler);
62119

63-
if(cmdline.isset("symbols"))
120+
if(!opt.has_value())
64121
{
65-
const std::string symbol_list(cmdline.get_value("symbols"));
66-
std::vector<std::string> result;
67-
split_string(symbol_list, ',', result, false, false);
122+
throw deserialization_exceptiont(
123+
"cannot read goto binary `" + binary + "`");
124+
}
68125

69-
goto_modelt goto_model;
70-
read_goto_binary(binary, goto_model, ui_message_handler);
126+
const goto_modelt goto_model(std::move(opt.value()));
71127

72-
symbol_analyzert analyzer(
73-
goto_model.symbol_table, gdb_api, ui_message_handler);
128+
symbol_analyzert analyzer(goto_model.symbol_table, gdb_api);
74129

75-
for(auto it = result.begin(); it != result.end(); it++)
76-
{
77-
messaget::result() << "analyzing symbol: " << (*it) << "\n";
78-
analyzer.analyse_symbol(*it);
79-
}
130+
analyzer.analyze_symbols(result);
80131

81-
messaget::result() << "GENERATED CODE: \n" << messaget::eom;
82-
messaget::result() << analyzer.get_code() << "\n" << messaget::eom;
132+
std::ofstream file;
83133

84-
gdb_api.terminate_gdb_process();
85-
return CPROVER_EXIT_SUCCESS;
134+
if(output_file)
135+
{
136+
file.open(cmdline.get_value("output-file"));
137+
}
138+
139+
std::ostream &out =
140+
output_file ? (std::ostream &)file : (std::ostream &)message.result();
141+
142+
if(symtab_snapshot)
143+
{
144+
symbol_tablet snapshot = analyzer.get_snapshot_as_symbol_table();
145+
show_symbol_table(snapshot, ui_message_handler);
146+
}
147+
else
148+
{
149+
std::string snapshot = analyzer.get_snapshot_as_c_code();
150+
out << snapshot;
151+
}
152+
153+
if(output_file)
154+
{
155+
file.close();
86156
}
87157
else
88158
{
89-
error() << "It is required to provide the symbols flag in order to make "
90-
<< "this tool work.\n"
91-
<< messaget::eom;
159+
message.result() << messaget::eom;
92160
}
93-
gdb_api.terminate_gdb_process();
94-
help();
95-
return CPROVER_EXIT_USAGE_ERROR;
161+
162+
return CPROVER_EXIT_SUCCESS;
96163
}
97164

98165
void memory_analyzer_parse_optionst::help()
99166
{
167+
message.status()
168+
<< '\n'
169+
<< banner_string("Memory-Analyzer", CBMC_VERSION) << '\n'
170+
<< align_center_with_border("Copyright (C) 2019") << '\n'
171+
<< align_center_with_border("Malte Mues, Diffblue Ltd.") << '\n'
172+
<< align_center_with_border("[email protected]") << '\n'
173+
<< '\n'
174+
<< "Usage: Purpose:\n"
175+
<< '\n'
176+
<< " memory-analyzer [-?] [-h] [--help] show help\n"
177+
<< " memory-analyzer --version show version\n"
178+
<< " memory-analyzer <options> <binary> analyze binary"
179+
<< "\n"
180+
<< " --core-file <file> analyze from core file\n"
181+
<< " --breakpoint <breakpoint> analyze from breakpoint\n"
182+
<< " --symbols <symbol-list> list of symbols to analyze\n"
183+
<< " --symtab-snapshot output snapshot as symbol table\n"
184+
<< " --output-file <file> write snapshot to file\n"
185+
<< messaget::eom;
100186
}
101187

102-
#endif // __linux__
188+
#endif
Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,53 @@
1-
// Copyright 2018 Author: Malte Mues <[email protected]>
1+
/*******************************************************************\
2+
3+
Module: Memory Analyzer
4+
5+
Author: Malte Mues <[email protected]>
6+
Daniel Poetzl
7+
8+
\*******************************************************************/
29

310
/// \file
411
/// This code does the command line parsing for the memory-analyzer tool
512

13+
// clang-format off
14+
#if defined(__linux__) || \
15+
defined(__FreeBSD_kernel__) || \
16+
defined(__GNU__) || \
17+
defined(__unix__) || \
18+
defined(__CYGWIN__) || \
19+
defined(__MACH__)
20+
// clang-format on
21+
622
#ifndef CPROVER_MEMORY_ANALYZER_MEMORY_ANALYZER_PARSE_OPTIONS_H
723
#define CPROVER_MEMORY_ANALYZER_MEMORY_ANALYZER_PARSE_OPTIONS_H
8-
#ifdef __linux__
24+
925
#include <util/parse_options.h>
1026
#include <util/ui_message.h>
1127

1228
// clang-format off
13-
#define MEMMORY_ANALYZER_OPTIONS \
29+
#define MEMORY_ANALYZER_OPTIONS \
30+
"(version)" \
31+
"(json-ui)" \
1432
"(core-file):" \
1533
"(breakpoint):" \
16-
"(symbols):"
17-
34+
"(symbols):" \
35+
"(symtab-snapshot)" \
36+
"(output-file):"
1837
// clang-format on
1938

20-
class memory_analyzer_parse_optionst : public parse_options_baset,
21-
public messaget
39+
class memory_analyzer_parse_optionst : public parse_options_baset
2240
{
2341
public:
42+
memory_analyzer_parse_optionst(int argc, const char *argv[]);
43+
2444
int doit() override;
2545
void help() override;
2646

27-
memory_analyzer_parse_optionst(int argc, const char **argv)
28-
: parse_options_baset(MEMMORY_ANALYZER_OPTIONS, argc, argv),
29-
messaget(ui_message_handler),
30-
ui_message_handler(cmdline, "memory-analyzer")
31-
{
32-
}
33-
3447
protected:
3548
ui_message_handlert ui_message_handler;
49+
messaget message;
3650
};
37-
#endif // __linux__
51+
3852
#endif // CPROVER_MEMORY_ANALYZER_MEMORY_ANALYZER_PARSE_OPTIONS_H
53+
#endif

0 commit comments

Comments
 (0)