atoll() is a terrible function -- you can't do any error checking with it.
Some of our option processing code uses it. This means that eg.
'--log-fd=9xxx' logs to fd 9, and '--log-fd=blahblahblah' logs to 0 (because
atoll() returns 0 if the string doesn't contain a number!)
It turns out that most of our option processing uses VG_(strtoll*) instead
of VG_(atoll). The reason that not all of it does is that the
option-processing macros are underpowered -- they currently work well if you
just want to assign the value to a variable, eg:
VG_BOOL_CLO(arg, "--heap", clo_heap)
else VG_BOOL_CLO(arg, "--stacks", clo_stacks)
else VG_NUM_CLO(arg, "--heap-admin", clo_heap_admin)
else VG_NUM_CLO(arg, "--depth", clo_depth)
(This works because they are actually an if-statement, but it looks odd.)
VG_NUM_CLO uses VG_(stroll10). But if you want to do any checking or
processing, you can't use those macros, leading to code like this:
else if (VG_CLO_STREQN(9, arg, "--log-fd=")) {
log_to = VgLogTo_Fd;
VG_(clo_log_name) = NULL;
tmp_log_fd = (Int)VG_(atoll)(&arg[9]);
}
So this commit:
- Improves the *_CLO_* macros so that they can be used in all circumstances.
They're now just expressions (albeit ones with side-effects, setting the
named variable appropriately). Thus they can be used as if-conditions,
and any post-checking or processing can occur in the then-statement. And
malformed numeric arguments (eg. --log-fd=foo) aren't accepted. This also
means you don't have to specify the lengths of any option strings anywhere
(eg. the 9 in the --log-fd example above). The use of a wrong number
caused at least one bug, in Massif.
- Updates all places where the macros were used.
- Updates Helgrind to use the *_CLO_* macros (it didn't use them).
- Updates Callgrind to use the *_CLO_* macros (it didn't use them), except
for the more esoteric option names (those with numbers in the option
name). This allowed getUInt() and getUWord() to be removed.
- Improves the cache option parsing in Cachegrind and Callgrind -- now uses
VG_(strtoll10)(), detects overflow, and is shorter.
- Uses INT instead of NUM in the macro names, to distinguish better vs. the
DBL macro.
- Removes VG_(atoll*) and the few remaining uses -- they're wretched
functions and VG_(strtoll*) should be used instead.
- Adds the VG_STREQN macro.
- Changes VG_BINT_CLO and VG_BHEX_CLO to abort if the given value is outside
the range -- the current silent truncation is likely to cause confusion as
much as anything.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9255 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c
index 36ddbab..e356d0e 100644
--- a/cachegrind/cg_main.c
+++ b/cachegrind/cg_main.c
@@ -1645,50 +1645,48 @@
static void parse_cache_opt ( cache_t* cache, Char* opt )
{
- Int i = 0, i2, i3;
+ Long i1, i2, i3;
+ Char* endptr;
- // Option argument looks like "65536,2,64".
- // Find commas, replace with NULs to make three independent
- // strings, then extract numbers, put NULs back. Yuck.
- while (VG_(isdigit)(opt[i])) i++;
- if (',' == opt[i]) {
- opt[i++] = '\0';
- i2 = i;
- } else goto bad;
- while (VG_(isdigit)(opt[i])) i++;
- if (',' == opt[i]) {
- opt[i++] = '\0';
- i3 = i;
- } else goto bad;
- while (VG_(isdigit)(opt[i])) i++;
- if ('\0' != opt[i]) goto bad;
+ // Option argument looks like "65536,2,64". Extract them.
+ i1 = VG_(strtoll10)(opt, &endptr); if (*endptr != ',') goto bad;
+ i2 = VG_(strtoll10)(endptr+1, &endptr); if (*endptr != ',') goto bad;
+ i3 = VG_(strtoll10)(endptr+1, &endptr); if (*endptr != '\0') goto bad;
- cache->size = (Int)VG_(atoll)(opt);
- cache->assoc = (Int)VG_(atoll)(opt + i2);
- cache->line_size = (Int)VG_(atoll)(opt + i3);
+ // Check for overflow.
+ cache->size = (Int)i1;
+ cache->assoc = (Int)i2;
+ cache->line_size = (Int)i3;
+ if (cache->size != i1) goto overflow;
+ if (cache->assoc != i2) goto overflow;
+ if (cache->line_size != i3) goto overflow;
- opt[i2-1] = ',';
- opt[i3-1] = ',';
return;
+ overflow:
+ VG_(message)(Vg_UserMsg,
+ "one of the cache parameters was too large and overflowed\n");
bad:
+ // XXX: this omits the "--I1/D1/L2=" part from the message, but that's
+ // not a big deal.
VG_(err_bad_option)(opt);
}
static Bool cg_process_cmd_line_option(Char* arg)
{
+ Char* tmp_str;
+
// 5 is length of "--I1="
- if (VG_CLO_STREQN(5, arg, "--I1="))
- parse_cache_opt(&clo_I1_cache, &arg[5]);
- else if (VG_CLO_STREQN(5, arg, "--D1="))
- parse_cache_opt(&clo_D1_cache, &arg[5]);
- else if (VG_CLO_STREQN(5, arg, "--L2="))
- parse_cache_opt(&clo_L2_cache, &arg[5]);
- else if (VG_CLO_STREQN(22, arg, "--cachegrind-out-file=")) {
- clo_cachegrind_out_file = &arg[22];
- }
- else VG_BOOL_CLO(arg, "--cache-sim", clo_cache_sim)
- else VG_BOOL_CLO(arg, "--branch-sim", clo_branch_sim)
+ if VG_STR_CLO(arg, "--I1", tmp_str)
+ parse_cache_opt(&clo_I1_cache, tmp_str);
+ else if VG_STR_CLO(arg, "--D1", tmp_str)
+ parse_cache_opt(&clo_D1_cache, tmp_str);
+ else if VG_STR_CLO(arg, "--L2", tmp_str)
+ parse_cache_opt(&clo_L2_cache, tmp_str);
+
+ else if VG_STR_CLO( arg, "--cachegrind-out-file", clo_cachegrind_out_file) {}
+ else if VG_BOOL_CLO(arg, "--cache-sim", clo_cache_sim) {}
+ else if VG_BOOL_CLO(arg, "--branch-sim", clo_branch_sim) {}
else
return False;
diff --git a/callgrind/clo.c b/callgrind/clo.c
index 238d872..7058926 100644
--- a/callgrind/clo.c
+++ b/callgrind/clo.c
@@ -395,251 +395,127 @@
/*--- Command line processing ---*/
/*--------------------------------------------------------------------*/
-static Char* getUInt(Char* s, UInt* pn)
-{
- UInt n = 0;
- while((*s >='0') && (*s <='9')) {
- n = 10*n + (*s-'0');
- s++;
- }
- if (pn) *pn = n;
- return s;
-}
-
-__attribute__((unused))
-static UWord getUWord(Char* s)
-{
- UWord n = 0;
- Bool isHex = False;
-
- if ((s[0] == '0') && (s[1] == 'x')) {
- isHex = True;
- s += 2;
- }
-
- if (!isHex) {
- while((*s >='0') && (*s <='9')) {
- n = 10*n + (*s-'0');
- s++;
- }
- }
- else {
- while(1) {
- if ((*s >='0') && (*s <='9')) {
- n = 16*n + (*s-'0');
- s++;
- continue;
- }
- if ((*s >='a') && (*s <='f')) {
- n = 16*n + (*s-'a'+10);
- s++;
- continue;
- }
- if ((*s >='A') && (*s <='F')) {
- n = 16*n + (*s-'A'+10);
- s++;
- continue;
- }
- break;
- }
- }
-
- return n;
-}
-
Bool CLG_(process_cmd_line_option)(Char* arg)
{
- if (0 == VG_(strcmp)(arg, "--skip-plt=yes"))
- CLG_(clo).skip_plt = True;
- else if (0 == VG_(strcmp)(arg, "--skip-plt=no"))
- CLG_(clo).skip_plt = False;
+ Char* tmp_str;
- else if (0 == VG_(strcmp)(arg, "--collect-jumps=yes"))
- CLG_(clo).collect_jumps = True;
- else if (0 == VG_(strcmp)(arg, "--collect-jumps=no"))
- CLG_(clo).collect_jumps = False;
+ if VG_BOOL_CLO(arg, "--skip-plt", CLG_(clo).skip_plt) {}
+
+ else if VG_BOOL_CLO(arg, "--collect-jumps", CLG_(clo).collect_jumps) {}
/* compatibility alias, deprecated option */
- else if (0 == VG_(strcmp)(arg, "--trace-jump=yes"))
- CLG_(clo).collect_jumps = True;
- else if (0 == VG_(strcmp)(arg, "--trace-jump=no"))
- CLG_(clo).collect_jumps = False;
+ else if VG_BOOL_CLO(arg, "--trace-jump", CLG_(clo).collect_jumps) {}
- else if (0 == VG_(strcmp)(arg, "--combine-dumps=yes"))
- CLG_(clo).combine_dumps = True;
- else if (0 == VG_(strcmp)(arg, "--combine-dumps=no"))
- CLG_(clo).combine_dumps = False;
+ else if VG_BOOL_CLO(arg, "--combine-dumps", CLG_(clo).combine_dumps) {}
- else if (0 == VG_(strcmp)(arg, "--collect-atstart=yes"))
- CLG_(clo).collect_atstart = True;
- else if (0 == VG_(strcmp)(arg, "--collect-atstart=no"))
- CLG_(clo).collect_atstart = False;
+ else if VG_BOOL_CLO(arg, "--collect-atstart", CLG_(clo).collect_atstart) {}
- else if (0 == VG_(strcmp)(arg, "--instr-atstart=yes"))
- CLG_(clo).instrument_atstart = True;
- else if (0 == VG_(strcmp)(arg, "--instr-atstart=no"))
- CLG_(clo).instrument_atstart = False;
+ else if VG_BOOL_CLO(arg, "--instr-atstart", CLG_(clo).instrument_atstart) {}
- else if (0 == VG_(strcmp)(arg, "--separate-threads=yes"))
- CLG_(clo).separate_threads = True;
- else if (0 == VG_(strcmp)(arg, "--separate-threads=no"))
- CLG_(clo).separate_threads = False;
+ else if VG_BOOL_CLO(arg, "--separate-threads", CLG_(clo).separate_threads) {}
- else if (0 == VG_(strcmp)(arg, "--compress-strings=yes"))
- CLG_(clo).compress_strings = True;
- else if (0 == VG_(strcmp)(arg, "--compress-strings=no"))
- CLG_(clo).compress_strings = False;
+ else if VG_BOOL_CLO(arg, "--compress-strings", CLG_(clo).compress_strings) {}
+ else if VG_BOOL_CLO(arg, "--compress-mangled", CLG_(clo).compress_mangled) {}
+ else if VG_BOOL_CLO(arg, "--compress-pos", CLG_(clo).compress_pos) {}
- else if (0 == VG_(strcmp)(arg, "--compress-mangled=yes"))
- CLG_(clo).compress_mangled = True;
- else if (0 == VG_(strcmp)(arg, "--compress-mangled=no"))
- CLG_(clo).compress_mangled = False;
-
- else if (0 == VG_(strcmp)(arg, "--compress-pos=yes"))
- CLG_(clo).compress_pos = True;
- else if (0 == VG_(strcmp)(arg, "--compress-pos=no"))
- CLG_(clo).compress_pos = False;
-
- else if (0 == VG_(strncmp)(arg, "--fn-skip=", 10)) {
- fn_config* fnc = get_fnc(arg+10);
+ else if VG_STR_CLO(arg, "--fn-skip", tmp_str) {
+ fn_config* fnc = get_fnc(tmp_str);
fnc->skip = CONFIG_TRUE;
}
- else if (0 == VG_(strncmp)(arg, "--dump-before=", 14)) {
- fn_config* fnc = get_fnc(arg+14);
+ else if VG_STR_CLO(arg, "--dump-before", tmp_str) {
+ fn_config* fnc = get_fnc(tmp_str);
fnc->dump_before = CONFIG_TRUE;
}
- else if (0 == VG_(strncmp)(arg, "--zero-before=", 14)) {
- fn_config* fnc = get_fnc(arg+14);
+ else if VG_STR_CLO(arg, "--zero-before", tmp_str) {
+ fn_config* fnc = get_fnc(tmp_str);
fnc->zero_before = CONFIG_TRUE;
}
- else if (0 == VG_(strncmp)(arg, "--dump-after=", 13)) {
- fn_config* fnc = get_fnc(arg+13);
+ else if VG_STR_CLO(arg, "--dump-after", tmp_str) {
+ fn_config* fnc = get_fnc(tmp_str);
fnc->dump_after = CONFIG_TRUE;
}
- else if (0 == VG_(strncmp)(arg, "--toggle-collect=", 17)) {
- fn_config* fnc = get_fnc(arg+17);
+ else if VG_STR_CLO(arg, "--toggle-collect", tmp_str) {
+ fn_config* fnc = get_fnc(tmp_str);
fnc->toggle_collect = CONFIG_TRUE;
/* defaults to initial collection off */
CLG_(clo).collect_atstart = False;
}
- else if (0 == VG_(strncmp)(arg, "--separate-recs=", 16))
- CLG_(clo).separate_recursions = (Int)VG_(atoll)(&arg[16]);
+ else if VG_INT_CLO(arg, "--separate-recs", CLG_(clo).separate_recursions) {}
/* change handling of a jump between functions to ret+call */
- else if (0 == VG_(strcmp)(arg, "--pop-on-jump")) {
- CLG_(clo).pop_on_jump = True;
- }
- else if (0 == VG_(strncmp)(arg, "--pop-on-jump=", 14)) {
- fn_config* fnc = get_fnc(arg+14);
+ else if VG_XACT_CLO(arg, "--pop-on-jump", CLG_(clo).pop_on_jump, True) {}
+ else if VG_STR_CLO( arg, "--pop-on-jump", tmp_str) {
+ fn_config* fnc = get_fnc(tmp_str);
fnc->pop_on_jump = CONFIG_TRUE;
}
#if CLG_ENABLE_DEBUG
- else if (0 == VG_(strncmp)(arg, "--ct-verbose=", 13))
- CLG_(clo).verbose = (Int)VG_(atoll)(&arg[13]);
+ else if VG_INT_CLO(arg, "--ct-verbose", CLG_(clo).verbose) {}
+ else if VG_INT_CLO(arg, "--ct-vstart", CLG_(clo).verbose_start) {}
- else if (0 == VG_(strncmp)(arg, "--ct-vstart=", 12))
- CLG_(clo).verbose_start = (ULong)VG_(atoll)(&arg[12]);
-
- else if (0 == VG_(strncmp)(arg, "--ct-verbose", 12)) {
- UInt n;
+ else if VG_STREQN(12, arg, "--ct-verbose") {
fn_config* fnc;
- Char* s = getUInt(arg+12, &n);
- if ((n == 0) || *s != '=') return False;
+ Char* s;
+ UInt n = VG_(strtoll10)(arg+12, &s);
+ if ((n <= 0) || *s != '=') return False;
fnc = get_fnc(s+1);
fnc->verbosity = n;
}
#endif
- else if (0 == VG_(strncmp)(arg, "--separate-callers=", 19)) {
- if (0 == VG_(strcmp)(arg+19, "auto"))
- CLG_(clo).separate_callers = CONFIG_AUTO;
- else
- CLG_(clo).separate_callers = (Int)VG_(atoll)(&arg[19]);
- }
+ else if VG_XACT_CLO(arg, "--separate-callers=auto",
+ CLG_(clo).separate_callers, CONFIG_AUTO) {}
+ else if VG_INT_CLO( arg, "--separate-callers",
+ CLG_(clo).separate_callers) {}
- else if (0 == VG_(strncmp)(arg, "--fn-group", 10)) {
- UInt n;
+ else if VG_STREQN(10, arg, "--fn-group") {
fn_config* fnc;
- Char* s = getUInt(arg+10, &n);
- if ((n == 0) || *s != '=') return False;
+ Char* s;
+ UInt n = VG_(strtoll10)(arg+10, &s);
+ if ((n <= 0) || *s != '=') return False;
fnc = get_fnc(s+1);
fnc->group = n;
}
- else if (0 == VG_(strncmp)(arg, "--separate-callers", 18)) {
- UInt n;
+ else if VG_STREQN(18, arg, "--separate-callers") {
fn_config* fnc;
- Char* s = getUInt(arg+18, &n);
- if ((n == 0) || *s != '=') return False;
+ Char* s;
+ UInt n = VG_(strtoll10)(arg+18, &s);
+ if ((n <= 0) || *s != '=') return False;
fnc = get_fnc(s+1);
fnc->separate_callers = n;
}
- else if (0 == VG_(strncmp)(arg, "--separate-recs", 15)) {
- UInt n;
+ else if VG_STREQN(15, arg, "--separate-recs") {
fn_config* fnc;
- Char* s = getUInt(arg+15, &n);
- if ((n == 0) || *s != '=') return False;
+ Char* s;
+ UInt n = VG_(strtoll10)(arg+15, &s);
+ if ((n <= 0) || *s != '=') return False;
fnc = get_fnc(s+1);
fnc->separate_recursions = n;
}
- else if (0 == VG_(strncmp)(arg, "--callgrind-out-file=", 21))
- CLG_(clo).out_format = VG_(strdup)("cl.clo.pclo.1", arg+21);
+ else if VG_STR_CLO(arg, "--callgrind-out-file", CLG_(clo).out_format) {}
- else if (0 == VG_(strcmp)(arg, "--mangle-names=yes"))
- CLG_(clo).mangle_names = True;
- else if (0 == VG_(strcmp)(arg, "--mangle-names=no"))
- CLG_(clo).mangle_names = False;
+ else if VG_BOOL_CLO(arg, "--mangle-names", CLG_(clo).mangle_names) {}
- else if (0 == VG_(strcmp)(arg, "--skip-direct-rec=yes"))
- CLG_(clo).skip_direct_recursion = True;
- else if (0 == VG_(strcmp)(arg, "--skip-direct-rec=no"))
- CLG_(clo).skip_direct_recursion = False;
+ else if VG_BOOL_CLO(arg, "--skip-direct-rec",
+ CLG_(clo).skip_direct_recursion) {}
- else if (0 == VG_(strcmp)(arg, "--dump-bbs=yes"))
- CLG_(clo).dump_bbs = True;
- else if (0 == VG_(strcmp)(arg, "--dump-bbs=no"))
- CLG_(clo).dump_bbs = False;
+ else if VG_BOOL_CLO(arg, "--dump-bbs", CLG_(clo).dump_bbs) {}
+ else if VG_BOOL_CLO(arg, "--dump-line", CLG_(clo).dump_line) {}
+ else if VG_BOOL_CLO(arg, "--dump-instr", CLG_(clo).dump_instr) {}
+ else if VG_BOOL_CLO(arg, "--dump-bb", CLG_(clo).dump_bb) {}
- else if (0 == VG_(strcmp)(arg, "--dump-line=yes"))
- CLG_(clo).dump_line = True;
- else if (0 == VG_(strcmp)(arg, "--dump-line=no"))
- CLG_(clo).dump_line = False;
+ else if VG_INT_CLO( arg, "--dump-every-bb", CLG_(clo).dump_every_bb) {}
- else if (0 == VG_(strcmp)(arg, "--dump-instr=yes"))
- CLG_(clo).dump_instr = True;
- else if (0 == VG_(strcmp)(arg, "--dump-instr=no"))
- CLG_(clo).dump_instr = False;
-
- else if (0 == VG_(strcmp)(arg, "--dump-bb=yes"))
- CLG_(clo).dump_bb = True;
- else if (0 == VG_(strcmp)(arg, "--dump-bb=no"))
- CLG_(clo).dump_bb = False;
-
- else if (0 == VG_(strncmp)(arg, "--dump-every-bb=", 16))
- CLG_(clo).dump_every_bb = (ULong)VG_(atoll)(&arg[16]);
-
-
- else if (0 == VG_(strcmp)(arg, "--collect-alloc=yes"))
- CLG_(clo).collect_alloc = True;
- else if (0 == VG_(strcmp)(arg, "--collect-alloc=no"))
- CLG_(clo).collect_alloc = False;
-
- else if (0 == VG_(strcmp)(arg, "--collect-systime=yes"))
- CLG_(clo).collect_systime = True;
- else if (0 == VG_(strcmp)(arg, "--collect-systime=no"))
- CLG_(clo).collect_systime = False;
-
- else if (0 == VG_(strcmp)(arg, "--simulate-cache=yes"))
- CLG_(clo).simulate_cache = True;
- else if (0 == VG_(strcmp)(arg, "--simulate-cache=no"))
- CLG_(clo).simulate_cache = False;
+ else if VG_BOOL_CLO(arg, "--collect-alloc", CLG_(clo).collect_alloc) {}
+ else if VG_BOOL_CLO(arg, "--collect-systime", CLG_(clo).collect_systime) {}
+ else if VG_BOOL_CLO(arg, "--simulate-cache", CLG_(clo).simulate_cache) {}
else {
Bool isCachesimOption = (*CLG_(cachesim).parse_opt)(arg);
diff --git a/callgrind/sim.c b/callgrind/sim.c
index 5208a72..d6c1211 100644
--- a/callgrind/sim.c
+++ b/callgrind/sim.c
@@ -1506,40 +1506,33 @@
);
}
-static void parse_opt ( cache_t* cache, char* orig_opt, int opt_len )
+static void parse_opt ( cache_t* cache, char* opt )
{
- int i1, i2, i3;
- int i;
- char *opt = VG_(strdup)("cl.sim.po.1", orig_opt);
+ Long i1, i2, i3;
+ Char* endptr;
- i = i1 = opt_len;
+ // Option argument looks like "65536,2,64". Extract them.
+ i1 = VG_(strtoll10)(opt, &endptr); if (*endptr != ',') goto bad;
+ i2 = VG_(strtoll10)(endptr+1, &endptr); if (*endptr != ',') goto bad;
+ i3 = VG_(strtoll10)(endptr+1, &endptr); if (*endptr != '\0') goto bad;
- /* Option looks like "--I1=65536,2,64".
- * Find commas, replace with NULs to make three independent
- * strings, then extract numbers. Yuck. */
- while (VG_(isdigit)(opt[i])) i++;
- if (',' == opt[i]) {
- opt[i++] = '\0';
- i2 = i;
- } else goto bad;
- while (VG_(isdigit)(opt[i])) i++;
- if (',' == opt[i]) {
- opt[i++] = '\0';
- i3 = i;
- } else goto bad;
- while (VG_(isdigit)(opt[i])) i++;
- if ('\0' != opt[i]) goto bad;
-
- cache->size = (Int)VG_(atoll)(opt + i1);
- cache->assoc = (Int)VG_(atoll)(opt + i2);
- cache->line_size = (Int)VG_(atoll)(opt + i3);
-
- VG_(free)(opt);
+ // Check for overflow.
+ cache->size = (Int)i1;
+ cache->assoc = (Int)i2;
+ cache->line_size = (Int)i3;
+ if (cache->size != i1) goto overflow;
+ if (cache->assoc != i2) goto overflow;
+ if (cache->line_size != i3) goto overflow;
return;
+ overflow:
+ VG_(message)(Vg_UserMsg,
+ "one of the cache parameters was too large and overflowed\n");
bad:
- VG_(err_bad_option)(orig_opt);
+ // XXX: this omits the "--I1/D1/L2=" part from the message, but that's
+ // not a big deal.
+ VG_(err_bad_option)(opt);
}
/* Check for command line option for cache configuration.
@@ -1549,36 +1542,25 @@
*/
static Bool cachesim_parse_opt(Char* arg)
{
- if (0 == VG_(strcmp)(arg, "--simulate-wb=yes"))
- clo_simulate_writeback = True;
- else if (0 == VG_(strcmp)(arg, "--simulate-wb=no"))
- clo_simulate_writeback = False;
+ Char* tmp_str;
- else if (0 == VG_(strcmp)(arg, "--simulate-hwpref=yes"))
- clo_simulate_hwpref = True;
- else if (0 == VG_(strcmp)(arg, "--simulate-hwpref=no"))
- clo_simulate_hwpref = False;
+ if VG_BOOL_CLO(arg, "--simulate-wb", clo_simulate_writeback) {}
+ else if VG_BOOL_CLO(arg, "--simulate-hwpref", clo_simulate_hwpref) {}
+ else if VG_BOOL_CLO(arg, "--simulate-sectors", clo_simulate_sectors) {}
- else if (0 == VG_(strcmp)(arg, "--simulate-sectors=yes"))
- clo_simulate_sectors = True;
- else if (0 == VG_(strcmp)(arg, "--simulate-sectors=no"))
- clo_simulate_sectors = False;
+ else if VG_BOOL_CLO(arg, "--cacheuse", clo_collect_cacheuse) {
+ if (clo_collect_cacheuse) {
+ /* Use counters only make sense with fine dumping */
+ CLG_(clo).dump_instr = True;
+ }
+ }
- else if (0 == VG_(strcmp)(arg, "--cacheuse=yes")) {
- clo_collect_cacheuse = True;
- /* Use counters only make sense with fine dumping */
- CLG_(clo).dump_instr = True;
- }
- else if (0 == VG_(strcmp)(arg, "--cacheuse=no"))
- clo_collect_cacheuse = False;
-
- /* 5 is length of "--I1=" */
- else if (0 == VG_(strncmp)(arg, "--I1=", 5))
- parse_opt(&clo_I1_cache, arg, 5);
- else if (0 == VG_(strncmp)(arg, "--D1=", 5))
- parse_opt(&clo_D1_cache, arg, 5);
- else if (0 == VG_(strncmp)(arg, "--L2=", 5))
- parse_opt(&clo_L2_cache, arg, 5);
+ else if VG_STR_CLO(arg, "--I1", tmp_str)
+ parse_opt(&clo_I1_cache, tmp_str);
+ else if VG_STR_CLO(arg, "--D1", tmp_str)
+ parse_opt(&clo_D1_cache, tmp_str);
+ else if VG_STR_CLO(arg, "--L2", tmp_str)
+ parse_opt(&clo_L2_cache, tmp_str);
else
return False;
diff --git a/coregrind/m_demangle/vg_libciface.h b/coregrind/m_demangle/vg_libciface.h
index a4bb105..44ca0c5 100644
--- a/coregrind/m_demangle/vg_libciface.h
+++ b/coregrind/m_demangle/vg_libciface.h
@@ -45,7 +45,7 @@
#define abort() vg_assert(0)
-#define atoi(_str) VG_(atoll)((_str))
+#define atoi(_str) VG_(strtoll10)((_str), NULL)
#define free(_pt) VG_(arena_free) (VG_AR_DEMANGLE,(_pt))
#define memcmp(_s1,_s2,_sz) VG_(memcmp)((_s1),(_s2),(_sz))
#define memcpy(_dd,_ss,_sz) VG_(memcpy)((_dd),(_ss),(_sz))
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index cf98350..abce99a 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -155,16 +155,6 @@
return n;
}
-Long VG_(atoll) ( Char* str )
-{
- return VG_(strtoll10)(str, NULL);
-}
-
-Long VG_(atoll16) ( Char* str )
-{
- return VG_(strtoll16)(str, NULL);
-}
-
/* ---------------------------------------------------------------------
String functions
------------------------------------------------------------------ */
diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c
index 9e4cd3e..bd31d63 100644
--- a/coregrind/m_libcproc.c
+++ b/coregrind/m_libcproc.c
@@ -401,8 +401,13 @@
res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
(UWord)pid, sizeof(pid));
if (!res.isError && res.res > 0) {
+ Char* s;
pid[res.res] = '\0';
- res.res = VG_(atoll)(pid);
+ res.res = VG_(strtoll10)(pid, &s);
+ if (*s != '\0') {
+ VG_(message)(Vg_DebugMsg,
+ "Warning: invalid file name linked to by /proc/self: %s", pid);
+ }
}
}
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 8322da5..f8258d4 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -273,31 +273,25 @@
str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
vg_assert(str);
- if (VG_STREQ(str, "--version")) {
- // Ensure the version string goes to stdout
- VG_(clo_log_fd) = 1;
+ // Nb: the version string goes to stdout.
+ if VG_XACT_CLO(str, "--version", VG_(clo_log_fd), 1) {
VG_(printf)("valgrind-" VERSION "\n");
VG_(exit)(0);
+ }
+ else if VG_XACT_CLO(str, "--help", *need_help, 1) {}
+ else if VG_XACT_CLO(str, "-h", *need_help, 1) {}
- } else if (VG_CLO_STREQ(str, "--help") ||
- VG_CLO_STREQ(str, "-h")) {
- *need_help = 1;
-
- } else if (VG_CLO_STREQ(str, "--help-debug")) {
- *need_help = 2;
+ else if VG_XACT_CLO(str, "--help-debug", *need_help, 2) {}
// The tool has already been determined, but we need to know the name
// here.
- } else if (VG_CLO_STREQN(7, str, "--tool=")) {
- *tool = &str[7];
+ else if VG_STR_CLO(str, "--tool", *tool) {}
// Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
// These are needed by VG_(ii_create_image), which happens
// before main_process_cmd_line_options().
- }
- else VG_NUM_CLO(str, "--max-stackframe", VG_(clo_max_stackframe))
- else VG_NUM_CLO(str, "--main-stacksize", VG_(clo_main_stacksize));
-
+ else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
+ else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
}
}
@@ -312,6 +306,7 @@
SysRes sres;
Int i, tmp_log_fd;
Int toolname_len = VG_(strlen)(toolname);
+ Char* tmp_str; // Used in a couple of places.
enum {
VgLogTo_Fd,
VgLogTo_File,
@@ -341,9 +336,9 @@
// in case someone has combined a prefix with a core-specific option,
// eg. "--memcheck:verbose".
if (*colon == ':') {
- if (VG_CLO_STREQN(2, arg, "--") &&
- VG_CLO_STREQN(toolname_len, arg+2, toolname) &&
- VG_CLO_STREQN(1, arg+2+toolname_len, ":"))
+ if (VG_STREQN(2, arg, "--") &&
+ VG_STREQN(toolname_len, arg+2, toolname) &&
+ VG_STREQN(1, arg+2+toolname_len, ":"))
{
// Prefix matches, convert "--toolname:foo" to "--foo".
// Two things to note:
@@ -373,134 +368,124 @@
}
/* Ignore these options - they've already been handled */
- if (VG_CLO_STREQN( 7, arg, "--tool=")) { }
- else if (VG_CLO_STREQN(20, arg, "--command-line-only=")) { }
- else if (VG_CLO_STREQ(arg, "--")) { }
- else if (VG_CLO_STREQ(arg, "-d")) { }
+ if VG_STREQN( 7, arg, "--tool=") {}
+ else if VG_STREQN(20, arg, "--command-line-only=") {}
+ else if VG_STREQ( arg, "--") {}
+ else if VG_STREQ( arg, "-d") {}
+ else if VG_STREQN(16, arg, "--max-stackframe") {}
+ else if VG_STREQN(16, arg, "--main-stacksize") {}
+ else if VG_STREQN(14, arg, "--profile-heap") {}
- else if (VG_CLO_STREQ(arg, "-v") ||
- VG_CLO_STREQ(arg, "--verbose"))
+ // These options are new.
+ else if (VG_STREQ(arg, "-v") ||
+ VG_STREQ(arg, "--verbose"))
VG_(clo_verbosity)++;
- else if (VG_CLO_STREQ(arg, "-q") ||
- VG_CLO_STREQ(arg, "--quiet"))
+ else if (VG_STREQ(arg, "-q") ||
+ VG_STREQ(arg, "--quiet"))
VG_(clo_verbosity)--;
- else VG_BOOL_CLO(arg, "--xml", VG_(clo_xml))
- else VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach))
- else VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle))
- else VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit))
- else VG_NUM_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode))
- else VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns))
+ else if VG_BOOL_CLO(arg, "--xml", VG_(clo_xml)) {}
+ else if VG_BOOL_CLO(arg, "--db-attach", VG_(clo_db_attach)) {}
+ else if VG_BOOL_CLO(arg, "--demangle", VG_(clo_demangle)) {}
+ else if VG_BOOL_CLO(arg, "--error-limit", VG_(clo_error_limit)) {}
+ else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
+ else if VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns)) {}
- /* The next two are already done in
- early_process_cmd_line_options, but we need to redundantly
- handle them again, so they do not get rejected as invalid. */
- else VG_NUM_CLO (arg, "--max-stackframe", VG_(clo_max_stackframe))
- else VG_NUM_CLO (arg, "--main-stacksize", VG_(clo_main_stacksize))
+ else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
+ else if VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main)) {}
+ else if VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp)) {}
+ else if VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds)) {}
+ else if VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children)) {}
+ else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
+ VG_(clo_child_silent_after_fork)) {}
+ else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched)) {}
+ else if VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals)) {}
+ else if VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab)) {}
+ else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
+ else if VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi)) {}
+ else if VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms),
+ True) {}
+ else if VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line),
+ True) {}
+ else if VG_XACT_CLO(arg, "--debug-dump=frames",
+ VG_(clo_debug_dump_frames), True) {}
+ else if VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir)) {}
- else VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres))
- else VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main))
- else VG_BOOL_CLO(arg, "--time-stamp", VG_(clo_time_stamp))
- else VG_BOOL_CLO(arg, "--track-fds", VG_(clo_track_fds))
- else VG_BOOL_CLO(arg, "--trace-children", VG_(clo_trace_children))
- else VG_BOOL_CLO(arg, "--child-silent-after-fork",
- VG_(clo_child_silent_after_fork))
- else VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched))
- else VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals))
- else VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab))
- else VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt))
- else VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi))
- else VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms))
- else VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line))
- else VG_XACT_CLO(arg, "--debug-dump=frames", VG_(clo_debug_dump_frames))
- else VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir))
+ else if VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls)) {}
+ else if VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb)) {}
+ else if VG_STR_CLO (arg, "--db-command", VG_(clo_db_command)) {}
+ else if VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints)) {}
+ else if VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets)) {}
+ else if VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info)) {}
- else VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls))
- else VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb))
- else VG_STR_CLO (arg, "--db-command", VG_(clo_db_command))
- else VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints))
- else VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets))
- else VG_BOOL_CLO(arg, "--read-var-info", VG_(clo_read_var_info))
+ else if VG_INT_CLO (arg, "--dump-error", VG_(clo_dump_error)) {}
+ else if VG_INT_CLO (arg, "--input-fd", VG_(clo_input_fd)) {}
+ else if VG_INT_CLO (arg, "--sanity-level", VG_(clo_sanity_level)) {}
+ else if VG_BINT_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
+ VG_DEEPEST_BACKTRACE) {}
- else VG_NUM_CLO (arg, "--dump-error", VG_(clo_dump_error))
- else VG_NUM_CLO (arg, "--input-fd", VG_(clo_input_fd))
- else VG_NUM_CLO (arg, "--sanity-level", VG_(clo_sanity_level))
- else VG_BNUM_CLO(arg, "--num-callers", VG_(clo_backtrace_size), 1,
- VG_DEEPEST_BACKTRACE)
+ else if VG_XACT_CLO(arg, "--smc-check=none", VG_(clo_smc_check),
+ Vg_SmcNone);
+ else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
+ Vg_SmcStack);
+ else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
+ Vg_SmcAll);
- else if (VG_CLO_STREQ(arg, "--smc-check=none"))
- VG_(clo_smc_check) = Vg_SmcNone;
- else if (VG_CLO_STREQ(arg, "--smc-check=stack"))
- VG_(clo_smc_check) = Vg_SmcStack;
- else if (VG_CLO_STREQ(arg, "--smc-check=all"))
- VG_(clo_smc_check) = Vg_SmcAll;
+ else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
- else if (VG_CLO_STREQ(arg, "--profile-heap=no"))
- ; /* We already handled it right at the top of valgrind_main.
- Just ignore. */
- else if (VG_CLO_STREQ(arg, "--profile-heap=yes"))
- ; /* ditto */
+ else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
+ VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
+ else if VG_BINT_CLO(arg, "--vex-iropt-level",
+ VG_(clo_vex_control).iropt_level, 0, 2) {}
+ else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
+ VG_(clo_vex_control).iropt_precise_memory_exns) {}
+ else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
+ VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
+ else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
+ VG_(clo_vex_control).guest_max_insns, 1, 100) {}
+ else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
+ VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
- else VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant))
-
- else VG_BNUM_CLO(arg, "--vex-iropt-verbosity",
- VG_(clo_vex_control).iropt_verbosity, 0, 10)
- else VG_BNUM_CLO(arg, "--vex-iropt-level",
- VG_(clo_vex_control).iropt_level, 0, 2)
- else VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
- VG_(clo_vex_control).iropt_precise_memory_exns)
- else VG_BNUM_CLO(arg, "--vex-iropt-unroll-thresh",
- VG_(clo_vex_control).iropt_unroll_thresh, 0, 400)
- else VG_BNUM_CLO(arg, "--vex-guest-max-insns",
- VG_(clo_vex_control).guest_max_insns, 1, 100)
- else VG_BNUM_CLO(arg, "--vex-guest-chase-thresh",
- VG_(clo_vex_control).guest_chase_thresh, 0, 99)
-
- else if (VG_CLO_STREQN(9, arg, "--log-fd=")) {
- log_to = VgLogTo_Fd;
+ else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
+ log_to = VgLogTo_Fd;
VG_(clo_log_name) = NULL;
- tmp_log_fd = (Int)VG_(atoll)(&arg[9]);
}
- else if (VG_CLO_STREQN(11, arg, "--log-file=")) {
- log_to = VgLogTo_File;
- VG_(clo_log_name) = &arg[11];
+ else if VG_STR_CLO(arg, "--log-file", VG_(clo_log_name)) {
+ log_to = VgLogTo_File;
}
- else if (VG_CLO_STREQN(13, arg, "--log-socket=")) {
- log_to = VgLogTo_Socket;
- VG_(clo_log_name) = &arg[13];
+ else if VG_STR_CLO(arg, "--log-socket", VG_(clo_log_name)) {
+ log_to = VgLogTo_Socket;
}
- else if (VG_CLO_STREQN(19, arg, "--xml-user-comment=")) {
- VG_(clo_xml_user_comment) = &arg[19];
- }
+ else if VG_STR_CLO(arg, "--xml-user-comment",
+ VG_(clo_xml_user_comment)) {}
- else if (VG_CLO_STREQN(15, arg, "--suppressions=")) {
+ else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
VG_(message)(Vg_UserMsg,
"Increase VG_CLO_MAX_SFILES and recompile.");
VG_(err_bad_option)(arg);
}
- VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &arg[15];
+ VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
VG_(clo_n_suppressions)++;
}
/* "stuvwxyz" --> stuvwxyz (binary) */
- else if (VG_CLO_STREQN(14, arg, "--trace-flags=")) {
+ else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
Int j;
- char* opt = & arg[14];
- if (8 != VG_(strlen)(opt)) {
+ if (8 != VG_(strlen)(tmp_str)) {
VG_(message)(Vg_UserMsg,
"--trace-flags argument must have 8 digits");
VG_(err_bad_option)(arg);
}
for (j = 0; j < 8; j++) {
- if ('0' == opt[j]) { /* do nothing */ }
- else if ('1' == opt[j]) VG_(clo_trace_flags) |= (1 << (7-j));
+ if ('0' == tmp_str[j]) { /* do nothing */ }
+ else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
else {
VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
"contain 0s and 1s");
@@ -510,18 +495,17 @@
}
/* "stuvwxyz" --> stuvwxyz (binary) */
- else if (VG_CLO_STREQN(16, arg, "--profile-flags=")) {
+ else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
Int j;
- char* opt = & arg[16];
- if (8 != VG_(strlen)(opt)) {
+ if (8 != VG_(strlen)(tmp_str)) {
VG_(message)(Vg_UserMsg,
"--profile-flags argument must have 8 digits");
VG_(err_bad_option)(arg);
}
for (j = 0; j < 8; j++) {
- if ('0' == opt[j]) { /* do nothing */ }
- else if ('1' == opt[j]) VG_(clo_profile_flags) |= (1 << (7-j));
+ if ('0' == tmp_str[j]) { /* do nothing */ }
+ else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
else {
VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
"contain 0s and 1s");
@@ -530,14 +514,14 @@
}
}
- else VG_NUM_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow))
+ else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
- else if (VG_CLO_STREQ(arg, "--gen-suppressions=no"))
- VG_(clo_gen_suppressions) = 0;
- else if (VG_CLO_STREQ(arg, "--gen-suppressions=yes"))
- VG_(clo_gen_suppressions) = 1;
- else if (VG_CLO_STREQ(arg, "--gen-suppressions=all"))
- VG_(clo_gen_suppressions) = 2;
+ else if VG_XACT_CLO(arg, "--gen-suppressions=no",
+ VG_(clo_gen_suppressions), 0) {}
+ else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
+ VG_(clo_gen_suppressions), 1) {}
+ else if VG_XACT_CLO(arg, "--gen-suppressions=all",
+ VG_(clo_gen_suppressions), 2) {}
else if ( ! VG_(needs).command_line_options
|| ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
@@ -1206,19 +1190,15 @@
// p: none
//--------------------------------------------------------------
/* Start the debugging-log system ASAP. First find out how many
- "-d"s were specified. This is a pre-scan of the command line. */
+ "-d"s were specified. This is a pre-scan of the command line. Also
+ get --profile-heap=yes which is needed by the time we start up dynamic
+ memory management. */
loglevel = 0;
for (i = 1; i < argc; i++) {
- if (argv[i][0] != '-')
- break;
- if (VG_STREQ(argv[i], "--"))
- break;
- if (VG_STREQ(argv[i], "-d"))
- loglevel++;
- if (VG_STREQ(argv[i], "--profile-heap=yes"))
- VG_(clo_profile_heap) = True;
- if (VG_STREQ(argv[i], "--profile-heap=no"))
- VG_(clo_profile_heap) = False;
+ if (argv[i][0] != '-') break;
+ if VG_STREQ(argv[i], "--") break;
+ if VG_STREQ(argv[i], "-d") loglevel++;
+ if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
}
/* ... and start the debug logger. Now we can safely emit logging
@@ -1330,6 +1310,7 @@
//--------------------------------------------------------------
// Start up the dynamic memory manager
// p: address space management
+ // p: getting --profile-heap
// In fact m_mallocfree is self-initialising, so there's no
// initialisation call to do. Instead, try a simple malloc/
// free pair right now to check that nothing is broken.
@@ -1481,7 +1462,9 @@
//--------------------------------------------------------------
// Load client executable, finding in $PATH if necessary
- // p: early_process_cmd_line_options() [for 'exec', 'need_help']
+ // p: early_process_cmd_line_options() [for 'exec', 'need_help',
+ // clo_max_stackframe,
+ // clo_main_stacksize]
// p: layout_remaining_space [so there's space]
//
// Set up client's environment
diff --git a/coregrind/m_replacemalloc/replacemalloc_core.c b/coregrind/m_replacemalloc/replacemalloc_core.c
index 175402b..4373232 100644
--- a/coregrind/m_replacemalloc/replacemalloc_core.c
+++ b/coregrind/m_replacemalloc/replacemalloc_core.c
@@ -53,13 +53,11 @@
Bool VG_(replacement_malloc_process_cmd_line_option)(Char* arg)
{
- if (VG_CLO_STREQN(12, arg, "--alignment=")) {
- VG_(clo_alignment) = (UInt)VG_(atoll)(&arg[12]);
-
- if (VG_(clo_alignment) < VG_MIN_MALLOC_SZB
- || VG_(clo_alignment) > 4096
- || VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */) {
- VG_(message)(Vg_UserMsg, "");
+ if VG_INT_CLO(arg, "--alignment", VG_(clo_alignment)) {
+ if (VG_(clo_alignment) < VG_MIN_MALLOC_SZB ||
+ VG_(clo_alignment) > 4096 ||
+ VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */)
+ {
VG_(message)(Vg_UserMsg,
"Invalid --alignment= setting. "
"Should be a power of 2, >= %d, <= 4096.", VG_MIN_MALLOC_SZB);
@@ -67,7 +65,7 @@
}
}
- else VG_BOOL_CLO(arg, "--trace-malloc", VG_(clo_trace_malloc))
+ else if VG_BOOL_CLO(arg, "--trace-malloc", VG_(clo_trace_malloc)) {}
else
return False;
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index ca07ffe..9e26c58 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -750,11 +750,16 @@
goto out;
if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
- Int fno = VG_(atoll)(d.d_name);
-
- if (fno != f.res)
- if (VG_(clo_track_fds))
- ML_(record_fd_open_named)(-1, fno);
+ Char* s;
+ Int fno = VG_(strtoll10)(d.d_name, &s);
+ if (*s == '\0') {
+ if (fno != f.res)
+ if (VG_(clo_track_fds))
+ ML_(record_fd_open_named)(-1, fno);
+ } else {
+ VG_(message)(Vg_DebugMsg,
+ "Warning: invalid file name in /proc/self/fd: %s", d.d_name);
+ }
}
VG_(lseek)(f.res, d.d_off, VKI_SEEK_SET);
diff --git a/drd/drd_main.c b/drd/drd_main.c
index 4792ffd..4ef3bb5 100644
--- a/drd/drd_main.c
+++ b/drd/drd_main.c
@@ -83,27 +83,27 @@
int trace_suppression = -1;
Char* trace_address = 0;
- VG_BOOL_CLO (arg, "--check-stack-var", check_stack_accesses)
- else VG_BOOL_CLO(arg, "--drd-stats", DRD_(s_print_stats))
- else VG_BOOL_CLO(arg,"--report-signal-unlocked",report_signal_unlocked)
- else VG_BOOL_CLO(arg, "--segment-merging", segment_merging)
- else VG_BOOL_CLO(arg, "--show-confl-seg", show_confl_seg)
- else VG_BOOL_CLO(arg, "--show-stack-usage", DRD_(s_show_stack_usage))
- else VG_BOOL_CLO(arg, "--trace-barrier", trace_barrier)
- else VG_BOOL_CLO(arg, "--trace-clientobj", trace_clientobj)
- else VG_BOOL_CLO(arg, "--trace-cond", trace_cond)
- else VG_BOOL_CLO(arg, "--trace-conflict-set", trace_conflict_set)
- else VG_BOOL_CLO(arg, "--trace-csw", trace_csw)
- else VG_BOOL_CLO(arg, "--trace-fork-join", trace_fork_join)
- else VG_BOOL_CLO(arg, "--trace-mutex", trace_mutex)
- else VG_BOOL_CLO(arg, "--trace-rwlock", trace_rwlock)
- else VG_BOOL_CLO(arg, "--trace-segment", trace_segment)
- else VG_BOOL_CLO(arg, "--trace-semaphore", trace_semaphore)
- else VG_BOOL_CLO(arg, "--trace-suppr", trace_suppression)
- else VG_BOOL_CLO(arg, "--var-info", DRD_(s_var_info))
- else VG_NUM_CLO (arg, "--exclusive-threshold", exclusive_threshold_ms)
- else VG_NUM_CLO (arg, "--shared-threshold", shared_threshold_ms)
- else VG_STR_CLO (arg, "--trace-addr", trace_address)
+ if VG_BOOL_CLO(arg, "--check-stack-var", check_stack_accesses) {}
+ else if VG_BOOL_CLO(arg, "--drd-stats", DRD_(s_print_stats)) {}
+ else if VG_BOOL_CLO(arg,"--report-signal-unlocked",report_signal_unlocked) {}
+ else if VG_BOOL_CLO(arg, "--segment-merging", segment_merging) {}
+ else if VG_BOOL_CLO(arg, "--show-confl-seg", show_confl_seg) {}
+ else if VG_BOOL_CLO(arg, "--show-stack-usage", DRD_(s_show_stack_usage)) {}
+ else if VG_BOOL_CLO(arg, "--trace-barrier", trace_barrier) {}
+ else if VG_BOOL_CLO(arg, "--trace-clientobj", trace_clientobj) {}
+ else if VG_BOOL_CLO(arg, "--trace-cond", trace_cond) {}
+ else if VG_BOOL_CLO(arg, "--trace-conflict-set", trace_conflict_set) {}
+ else if VG_BOOL_CLO(arg, "--trace-csw", trace_csw) {}
+ else if VG_BOOL_CLO(arg, "--trace-fork-join", trace_fork_join) {}
+ else if VG_BOOL_CLO(arg, "--trace-mutex", trace_mutex) {}
+ else if VG_BOOL_CLO(arg, "--trace-rwlock", trace_rwlock) {}
+ else if VG_BOOL_CLO(arg, "--trace-segment", trace_segment) {}
+ else if VG_BOOL_CLO(arg, "--trace-semaphore", trace_semaphore) {}
+ else if VG_BOOL_CLO(arg, "--trace-suppr", trace_suppression) {}
+ else if VG_BOOL_CLO(arg, "--var-info", DRD_(s_var_info)) {}
+ else if VG_INT_CLO (arg, "--exclusive-threshold", exclusive_threshold_ms) {}
+ else if VG_INT_CLO (arg, "--shared-threshold", shared_threshold_ms) {}
+ else if VG_STR_CLO (arg, "--trace-addr", trace_address) {}
else
return VG_(replacement_malloc_process_cmd_line_option)(arg);
diff --git a/exp-ptrcheck/pc_common.c b/exp-ptrcheck/pc_common.c
index 8f9bef6..dc4b622 100644
--- a/exp-ptrcheck/pc_common.c
+++ b/exp-ptrcheck/pc_common.c
@@ -64,9 +64,9 @@
Bool pc_process_cmd_line_options(Char* arg)
{
- VG_BOOL_CLO(arg, "--partial-loads-ok", h_clo_partial_loads_ok)
- /* else VG_BOOL_CLO(arg, "--lossage-check", h_clo_lossage_check) */
- else VG_BOOL_CLO(arg, "--enable-sg-checks", sg_clo_enable_sg_checks)
+ if VG_BOOL_CLO(arg, "--partial-loads-ok", h_clo_partial_loads_ok) {}
+ /* else if VG_BOOL_CLO(arg, "--lossage-check", h_clo_lossage_check) {} */
+ else if VG_BOOL_CLO(arg, "--enable-sg-checks", sg_clo_enable_sg_checks) {}
else
return VG_(replacement_malloc_process_cmd_line_option)(arg);
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index be0d408..d2915e4 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -4009,39 +4009,32 @@
static Bool hg_process_cmd_line_option ( Char* arg )
{
- if (VG_CLO_STREQ(arg, "--track-lockorders=no"))
- HG_(clo_track_lockorders) = False;
- else if (VG_CLO_STREQ(arg, "--track-lockorders=yes"))
- HG_(clo_track_lockorders) = True;
+ Char* tmp_str;
- else if (VG_CLO_STREQ(arg, "--cmp-race-err-addrs=no"))
- HG_(clo_cmp_race_err_addrs) = False;
- else if (VG_CLO_STREQ(arg, "--cmp-race-err-addrs=yes"))
- HG_(clo_cmp_race_err_addrs) = True;
-
- else if (VG_CLO_STREQ(arg, "--show-conflicts=no"))
- HG_(clo_show_conflicts) = False;
- else if (VG_CLO_STREQ(arg, "--show-conflicts=yes"))
- HG_(clo_show_conflicts) = True;
+ if VG_BOOL_CLO(arg, "--track-lockorders",
+ HG_(clo_track_lockorders)) {}
+ else if VG_BOOL_CLO(arg, "--cmp-race-err-addrs",
+ HG_(clo_cmp_race_err_addrs)) {}
+ else if VG_BOOL_CLO(arg, "--show-conflicts",
+ HG_(clo_show_conflicts)) {}
/* If you change the 10k/10mill limits, remember to also change
them in assertions at the top of event_map_maybe_GC. */
- else VG_BNUM_CLO(arg, "--conflict-cache-size",
- HG_(clo_conflict_cache_size), 10*1000, 10*1000*1000)
+ else if VG_BINT_CLO(arg, "--conflict-cache-size",
+ HG_(clo_conflict_cache_size), 10*1000, 10*1000*1000) {}
/* "stuvwx" --> stuvwx (binary) */
- else if (VG_CLO_STREQN(18, arg, "--hg-sanity-flags=")) {
+ else if VG_STR_CLO(arg, "--hg-sanity-flags", tmp_str) {
Int j;
- Char* opt = & arg[18];
- if (6 != VG_(strlen)(opt)) {
+ if (6 != VG_(strlen)(tmp_str)) {
VG_(message)(Vg_UserMsg,
"--hg-sanity-flags argument must have 6 digits");
return False;
}
for (j = 0; j < 6; j++) {
- if ('0' == opt[j]) { /* do nothing */ }
- else if ('1' == opt[j]) HG_(clo_sanity_flags) |= (1 << (6-1-j));
+ if ('0' == tmp_str[j]) { /* do nothing */ }
+ else if ('1' == tmp_str[j]) HG_(clo_sanity_flags) |= (1 << (6-1-j));
else {
VG_(message)(Vg_UserMsg, "--hg-sanity-flags argument can "
"only contain 0s and 1s");
diff --git a/include/pub_tool_libcbase.h b/include/pub_tool_libcbase.h
index bc224ac..96eae4c 100644
--- a/include/pub_tool_libcbase.h
+++ b/include/pub_tool_libcbase.h
@@ -51,32 +51,33 @@
// is set to the start of the string. None of them test that the number
// fits into 64 bits.
//
-// Nb: if you're wondering why we don't just have a single VG_(strtol) which
+// Nb: if you're wondering why we don't just have a single VG_(strtoll) which
// takes a base, it's because I wanted it to assert if it was given a bogus
// base (the standard glibc one sets 'errno' in this case). But
// m_libcbase.c doesn't import any code, not even vg_assert. --njn
+//
+// Nb: we also don't provide VG_(atoll*); these functions are worse than
+// useless because they don't do any error checking and so accept malformed
+// numbers and non-numbers -- eg. "123xyz" gives 123, and "foo" gives 0!
+// If you really want that behaviour, you can use "VG_(strtoll10)(str, NULL)".
extern Long VG_(strtoll10) ( Char* str, Char** endptr );
extern Long VG_(strtoll16) ( Char* str, Char** endptr );
- // Convert a string to a double. After leading whitespace is ignored, a
- // '+' or '-' is allowed, and then it accepts a non-empty sequence of
- // decimal digits possibly containing a '.'. Hexadecimal floats are not
- // accepted, nor are "fancy" floats (eg. "3.4e-5", "NAN").
+// Convert a string to a double. After leading whitespace is ignored, a
+// '+' or '-' is allowed, and then it accepts a non-empty sequence of
+// decimal digits possibly containing a '.'. Hexadecimal floats are not
+// accepted, nor are "fancy" floats (eg. "3.4e-5", "NAN").
extern double VG_(strtod) ( Char* str, Char** endptr );
- // These are just like their VG_(strtoll*) counterparts, except that you
- // cannot tell if an error occurred (because 0 is returned) or if there
- // is any trailing non-numeric characterws (eg. in "123xyz").
-extern Long VG_(atoll) ( Char* str ); // base 10
-extern Long VG_(atoll16) ( Char* str ); // base 16; leading 0x accepted
-
/* ---------------------------------------------------------------------
String functions and macros
------------------------------------------------------------------ */
-/* Use this for normal null-termination-style string comparison */
+/* Use this for normal null-termination-style string comparison. */
#define VG_STREQ(s1,s2) ( (s1 != NULL && s2 != NULL \
&& VG_(strcmp)((s1),(s2))==0) ? True : False )
+#define VG_STREQN(n,s1,s2) ( (s1 != NULL && s2 != NULL \
+ && VG_(strncmp)((s1),(s2),(n))==0) ? True : False )
extern SizeT VG_(strlen) ( const Char* str );
extern Char* VG_(strcat) ( Char* dest, const Char* src );
diff --git a/include/pub_tool_options.h b/include/pub_tool_options.h
index a45ce25..89e0ca6 100644
--- a/include/pub_tool_options.h
+++ b/include/pub_tool_options.h
@@ -34,71 +34,110 @@
#include "libvex.h" // for VexControl
-/* Use these for recognising tool command line options -- stops comparing
- once whitespace is reached. */
-#define VG_CLO_STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
-#define VG_CLO_STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
+// Higher-level command-line option recognisers; use in if/else chains.
+// Note that they assign a value to the 'qq_var' argument. So often they
+// can be used like this:
+//
+// if VG_STR_CLO(arg, "--foo", clo_foo) { }
+//
+// But if you want to do further checking or processing, you can do this:
+//
+// if VG_STR_CLO(arg, "--foo", clo_foo) { <further checking or processing> }
+//
+// They use GNU statement expressions to do the qq_var assignment within a
+// conditional expression.
-/* Higher-level command-line option recognisers; use in if/else chains */
-
+// String argument, eg. --foo=yes or --foo=no
#define VG_BOOL_CLO(qq_arg, qq_option, qq_var) \
- if (VG_CLO_STREQ(qq_arg, qq_option"=yes")) { (qq_var) = True; } \
- else if (VG_CLO_STREQ(qq_arg, qq_option"=no")) { (qq_var) = False; }
+ (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \
+ ({ \
+ Char* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
+ if VG_STREQ(val, "yes") (qq_var) = True; \
+ else if VG_STREQ(val, "no") (qq_var) = False; \
+ True; \
+ }) \
+ )
+// String argument, eg. --foo=bar
#define VG_STR_CLO(qq_arg, qq_option, qq_var) \
- if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
- (qq_var) = &qq_arg[ VG_(strlen)(qq_option)+1 ]; \
- }
+ (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \
+ ({ \
+ Char* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
+ (qq_var) = val; \
+ True; \
+ }) \
+ )
-/* Unbounded integer arg */
-#define VG_NUM_CLO(qq_arg, qq_option, qq_var) \
- if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
+// Unbounded integer arg, eg. --foo=10
+#define VG_INT_CLO(qq_arg, qq_option, qq_var) \
+ (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \
+ ({ \
+ Char* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
Char* s; \
- Long n = VG_(strtoll10)( &qq_arg[ VG_(strlen)(qq_option)+1 ], &s );\
+ Long n = VG_(strtoll10)( val, &s ); \
(qq_var) = n; \
- /* Check for non-numeralness, or overflow */ \
+ /* Check for non-numeralness, or overflow. */ \
if ('\0' != s[0] || (qq_var) != n) VG_(err_bad_option)(qq_arg); \
- }
+ True; \
+ }) \
+ )
-/* Bounded integer arg */
-#define VG_BNUM_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
- if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
+// Bounded integer arg, eg. --foo=10 ; if the value exceeds the bounds it
+// causes an abort. 'qq_base' can be 10 or 16.
+#define VG_BINTN_CLO(qq_base, qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
+ (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \
+ ({ \
+ Char* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
Char* s; \
- Long n = VG_(strtoll10)( &qq_arg[ VG_(strlen)(qq_option)+1 ], &s );\
+ Long n = VG_(strtoll##qq_base)( val, &s ); \
(qq_var) = n; \
- /* Check for non-numeralness, or overflow */ \
+ /* Check for non-numeralness, or overflow. */ \
+ /* Nb: it will overflow if qq_var is unsigned and qq_val is negative! */ \
if ('\0' != s[0] || (qq_var) != n) VG_(err_bad_option)(qq_arg); \
- if ((qq_var) < (qq_lo)) (qq_var) = (qq_lo); \
- if ((qq_var) > (qq_hi)) (qq_var) = (qq_hi); \
- }
+ /* Check bounds. */ \
+ if ((qq_var) < (qq_lo) || (qq_var) > (qq_hi)) { \
+ VG_(message)(Vg_UserMsg, \
+ "'%s' argument must be between %lld and %lld", \
+ (qq_option), (Long)(qq_lo), (Long)(qq_hi)); \
+ VG_(err_bad_option)(qq_arg); \
+ } \
+ True; \
+ }) \
+ )
-/* Bounded hexadecimal arg */
+// Bounded decimal integer arg, eg. --foo=100
+#define VG_BINT_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
+ VG_BINTN_CLO(10, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi))
+
+// Bounded hexadecimal integer arg, eg. --foo=0x1fa8
#define VG_BHEX_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
- if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
- Char* s; \
- Long n = VG_(strtoll16)( &qq_arg[ VG_(strlen)(qq_option)+1 ], &s );\
- (qq_var) = n; \
- /* Check for non-numeralness, or overflow */ \
- if ('\0' != s[0] || (qq_var) != n) VG_(err_bad_option)(qq_arg); \
- if ((qq_var) < (qq_lo)) (qq_var) = (qq_lo); \
- if ((qq_var) > (qq_hi)) (qq_var) = (qq_hi); \
- }
+ VG_BINTN_CLO(16, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi))
-/* Double arg */
+// Double (decimal) arg, eg. --foo=4.6
+// XXX: there's not VG_BDBL_CLO because we don't have a good way of printing
+// floats at the moment!
#define VG_DBL_CLO(qq_arg, qq_option, qq_var) \
- if (VG_CLO_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) { \
+ (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \
+ ({ \
+ Char* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
Char* s; \
- double n = VG_(strtod)( &qq_arg[ VG_(strlen)(qq_option)+1 ], &s );\
+ double n = VG_(strtod)( val, &s ); \
(qq_var) = n; \
/* Check for non-numeralness */ \
if ('\0' != s[0]) VG_(err_bad_option)(qq_arg); \
- }
+ True; \
+ }) \
+ )
-/* Bool arg whose value is denoted by the exact presence of the given string. */
-#define VG_XACT_CLO(qq_arg, qq_option, qq_var) \
- if (VG_CLO_STREQ(qq_arg, qq_option)) { \
- (qq_var) = True; \
- } /* else leave it alone */
+// Arg whose value is denoted by the exact presence of the given string;
+// if it matches, qq_var is assigned the value in qq_val.
+#define VG_XACT_CLO(qq_arg, qq_option, qq_var, qq_val) \
+ (VG_STREQ((qq_arg), (qq_option)) && \
+ ({ \
+ (qq_var) = (qq_val); \
+ True; \
+ }) \
+ )
/* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */
extern Int VG_(clo_verbosity);
@@ -125,9 +164,10 @@
/* Call this if a recognised option was bad for some reason. Note:
don't use it just because an option was unrecognised -- return
- 'False' from VG_(tdict).tool_process_cmd_line_option) to indicate
- that. This function prints an error message, then shuts down the
- entire system. */
+ 'False' from VG_(tdict).tool_process_cmd_line_option) to indicate that --
+ use it if eg. an option was given an inappropriate argument.
+ This function prints an error message, then shuts down the entire system.
+ It returns a Bool so it can be used in the _CLO_ macros. */
__attribute__((noreturn))
extern void VG_(err_bad_option) ( Char* opt );
diff --git a/lackey/lk_main.c b/lackey/lk_main.c
index 737e92c..dd502c5 100644
--- a/lackey/lk_main.c
+++ b/lackey/lk_main.c
@@ -196,11 +196,11 @@
static Bool lk_process_cmd_line_option(Char* arg)
{
- VG_STR_CLO(arg, "--fnname", clo_fnname)
- else VG_BOOL_CLO(arg, "--basic-counts", clo_basic_counts)
- else VG_BOOL_CLO(arg, "--detailed-counts", clo_detailed_counts)
- else VG_BOOL_CLO(arg, "--trace-mem", clo_trace_mem)
- else VG_BOOL_CLO(arg, "--trace-superblocks", clo_trace_sbs)
+ if VG_STR_CLO(arg, "--fnname", clo_fnname) {}
+ else if VG_BOOL_CLO(arg, "--basic-counts", clo_basic_counts) {}
+ else if VG_BOOL_CLO(arg, "--detailed-counts", clo_detailed_counts) {}
+ else if VG_BOOL_CLO(arg, "--trace-mem", clo_trace_mem) {}
+ else if VG_BOOL_CLO(arg, "--trace-superblocks", clo_trace_sbs) {}
else
return False;
diff --git a/massif/ms_main.c b/massif/ms_main.c
index 32b6eec..2d8c26a 100644
--- a/massif/ms_main.c
+++ b/massif/ms_main.c
@@ -358,46 +358,45 @@
// word-sized type -- it ended up with a value of 4.2 billion. Sigh.
static SSizeT clo_heap_admin = 8;
static Bool clo_stacks = False;
-static UInt clo_depth = 30;
+static Int clo_depth = 30;
static double clo_threshold = 1.0; // percentage
static double clo_peak_inaccuracy = 1.0; // percentage
-static UInt clo_time_unit = TimeI;
-static UInt clo_detailed_freq = 10;
-static UInt clo_max_snapshots = 100;
+static Int clo_time_unit = TimeI;
+static Int clo_detailed_freq = 10;
+static Int clo_max_snapshots = 100;
static Char* clo_massif_out_file = "massif.out.%p";
static XArray* args_for_massif;
static Bool ms_process_cmd_line_option(Char* arg)
{
+ Char* tmp_str;
+
// Remember the arg for later use.
VG_(addToXA)(args_for_massif, &arg);
- VG_BOOL_CLO(arg, "--heap", clo_heap)
- else VG_BOOL_CLO(arg, "--stacks", clo_stacks)
+ if VG_BOOL_CLO(arg, "--heap", clo_heap) {}
+ else if VG_BOOL_CLO(arg, "--stacks", clo_stacks) {}
- else VG_NUM_CLO(arg, "--heap-admin", clo_heap_admin)
- else VG_NUM_CLO(arg, "--depth", clo_depth)
+ else if VG_BINT_CLO(arg, "--heap-admin", clo_heap_admin, 0, 1024) {}
+ else if VG_BINT_CLO(arg, "--depth", clo_depth, 1, MAX_DEPTH) {}
- else VG_DBL_CLO(arg, "--threshold", clo_threshold)
+ else if VG_DBL_CLO(arg, "--threshold", clo_threshold) {}
- else VG_DBL_CLO(arg, "--peak-inaccuracy", clo_peak_inaccuracy)
+ else if VG_DBL_CLO(arg, "--peak-inaccuracy", clo_peak_inaccuracy) {}
- else VG_NUM_CLO(arg, "--detailed-freq", clo_detailed_freq)
- else VG_NUM_CLO(arg, "--max-snapshots", clo_max_snapshots)
+ else if VG_BINT_CLO(arg, "--detailed-freq", clo_detailed_freq, 1, 10000) {}
+ else if VG_BINT_CLO(arg, "--max-snapshots", clo_max_snapshots, 10, 1000) {}
- else if (VG_CLO_STREQ(arg, "--time-unit=i")) clo_time_unit = TimeI;
- else if (VG_CLO_STREQ(arg, "--time-unit=ms")) clo_time_unit = TimeMS;
- else if (VG_CLO_STREQ(arg, "--time-unit=B")) clo_time_unit = TimeB;
+ else if VG_XACT_CLO(arg, "--time-unit=i", clo_time_unit, TimeI) {}
+ else if VG_XACT_CLO(arg, "--time-unit=ms", clo_time_unit, TimeMS) {}
+ else if VG_XACT_CLO(arg, "--time-unit=B", clo_time_unit, TimeB) {}
- else if (VG_CLO_STREQN(11, arg, "--alloc-fn=")) {
- Char* alloc_fn = &arg[11];
- VG_(addToXA)(alloc_fns, &alloc_fn);
+ else if VG_STR_CLO(arg, "--alloc-fn", tmp_str) {
+ VG_(addToXA)(alloc_fns, &tmp_str);
}
- else if (VG_CLO_STREQN(18, arg, "--massif-out-file=")) {
- clo_massif_out_file = &arg[18];
- }
+ else if VG_STR_CLO(arg, "--massif-out-file", clo_massif_out_file) {}
else
return VG_(replacement_malloc_process_cmd_line_option)(arg);
@@ -2164,26 +2163,10 @@
Int i;
// Check options.
- if (clo_heap_admin < 0 || clo_heap_admin > 1024) {
- VG_(message)(Vg_UserMsg, "--heap-admin must be between 0 and 1024");
- VG_(err_bad_option)("--heap-admin");
- }
- if (clo_depth < 1 || clo_depth > MAX_DEPTH) {
- VG_(message)(Vg_UserMsg, "--depth must be between 1 and %d", MAX_DEPTH);
- VG_(err_bad_option)("--depth");
- }
if (clo_threshold < 0 || clo_threshold > 100) {
VG_(message)(Vg_UserMsg, "--threshold must be between 0.0 and 100.0");
VG_(err_bad_option)("--threshold");
}
- if (clo_detailed_freq < 1 || clo_detailed_freq > 10000) {
- VG_(message)(Vg_UserMsg, "--detailed-freq must be between 1 and 10000");
- VG_(err_bad_option)("--detailed-freq");
- }
- if (clo_max_snapshots < 10 || clo_max_snapshots > 1000) {
- VG_(message)(Vg_UserMsg, "--max-snapshots must be between 10 and 1000");
- VG_(err_bad_option)("--max-snapshots");
- }
// If we have --heap=no, set --heap-admin to zero, just to make sure we
// don't accidentally use a non-zero heap-admin size somewhere.
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index b363835..4c474d4 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -4672,6 +4672,10 @@
static Bool mc_process_cmd_line_options(Char* arg)
{
+ Char* tmp_str;
+ Char* bad_level_msg =
+ "ERROR: --track-origins=yes has no effect when --undef-value-errors=no";
+
tl_assert( MC_(clo_mc_level) >= 1 && MC_(clo_mc_level) <= 3 );
/* Set MC_(clo_mc_level):
@@ -4684,10 +4688,13 @@
--track-origins=yes as meaningless.
*/
if (0 == VG_(strcmp)(arg, "--undef-value-errors=no")) {
- if (MC_(clo_mc_level) == 3)
- goto mc_level_error;
- MC_(clo_mc_level) = 1;
- return True;
+ if (MC_(clo_mc_level) == 3) {
+ VG_(message)(Vg_DebugMsg, "%s", bad_level_msg);
+ return False;
+ } else {
+ MC_(clo_mc_level) = 1;
+ return True;
+ }
}
if (0 == VG_(strcmp)(arg, "--undef-value-errors=yes")) {
if (MC_(clo_mc_level) == 1)
@@ -4700,38 +4707,42 @@
return True;
}
if (0 == VG_(strcmp)(arg, "--track-origins=yes")) {
- if (MC_(clo_mc_level) == 1)
- goto mc_level_error;
- MC_(clo_mc_level) = 3;
- return True;
+ if (MC_(clo_mc_level) == 1) {
+ VG_(message)(Vg_DebugMsg, "%s", bad_level_msg);
+ return False;
+ } else {
+ MC_(clo_mc_level) = 3;
+ return True;
+ }
}
- VG_BOOL_CLO(arg, "--partial-loads-ok", MC_(clo_partial_loads_ok))
- else VG_BOOL_CLO(arg, "--show-reachable", MC_(clo_show_reachable))
- else VG_BOOL_CLO(arg, "--workaround-gcc296-bugs",MC_(clo_workaround_gcc296_bugs))
+ if VG_BOOL_CLO(arg, "--partial-loads-ok", MC_(clo_partial_loads_ok)) {}
+ else if VG_BOOL_CLO(arg, "--show-reachable", MC_(clo_show_reachable)) {}
+ else if VG_BOOL_CLO(arg, "--workaround-gcc296-bugs",
+ MC_(clo_workaround_gcc296_bugs)) {}
- else VG_BNUM_CLO(arg, "--freelist-vol", MC_(clo_freelist_vol),
- 0, 10*1000*1000*1000LL)
+ else if VG_BINT_CLO(arg, "--freelist-vol", MC_(clo_freelist_vol),
+ 0, 10*1000*1000*1000LL) {}
- else if (VG_CLO_STREQ(arg, "--leak-check=no"))
- MC_(clo_leak_check) = LC_Off;
- else if (VG_CLO_STREQ(arg, "--leak-check=summary"))
- MC_(clo_leak_check) = LC_Summary;
- else if (VG_CLO_STREQ(arg, "--leak-check=yes") ||
- VG_CLO_STREQ(arg, "--leak-check=full"))
- MC_(clo_leak_check) = LC_Full;
+ else if VG_XACT_CLO(arg, "--leak-check=no",
+ MC_(clo_leak_check), LC_Off) {}
+ else if VG_XACT_CLO(arg, "--leak-check=summary",
+ MC_(clo_leak_check), LC_Summary) {}
+ else if VG_XACT_CLO(arg, "--leak-check=yes",
+ MC_(clo_leak_check), LC_Full) {}
+ else if VG_XACT_CLO(arg, "--leak-check=full",
+ MC_(clo_leak_check), LC_Full) {}
- else if (VG_CLO_STREQ(arg, "--leak-resolution=low"))
- MC_(clo_leak_resolution) = Vg_LowRes;
- else if (VG_CLO_STREQ(arg, "--leak-resolution=med"))
- MC_(clo_leak_resolution) = Vg_MedRes;
- else if (VG_CLO_STREQ(arg, "--leak-resolution=high"))
- MC_(clo_leak_resolution) = Vg_HighRes;
+ else if VG_XACT_CLO(arg, "--leak-resolution=low",
+ MC_(clo_leak_resolution), Vg_LowRes) {}
+ else if VG_XACT_CLO(arg, "--leak-resolution=med",
+ MC_(clo_leak_resolution), Vg_MedRes) {}
+ else if VG_XACT_CLO(arg, "--leak-resolution=high",
+ MC_(clo_leak_resolution), Vg_HighRes) {}
- else if (VG_CLO_STREQN(16,arg,"--ignore-ranges=")) {
- Int i;
- UChar* txt = (UChar*)(arg+16);
- Bool ok = parse_ignore_ranges(txt);
+ else if VG_STR_CLO(arg, "--ignore-ranges", tmp_str) {
+ Int i;
+ Bool ok = parse_ignore_ranges(tmp_str);
if (!ok)
return False;
tl_assert(ignoreRanges.used >= 0);
@@ -4757,19 +4768,13 @@
}
}
- else VG_BHEX_CLO(arg, "--malloc-fill", MC_(clo_malloc_fill), 0x00, 0xFF)
- else VG_BHEX_CLO(arg, "--free-fill", MC_(clo_free_fill), 0x00, 0xFF)
+ else if VG_BHEX_CLO(arg, "--malloc-fill", MC_(clo_malloc_fill), 0x00,0xFF) {}
+ else if VG_BHEX_CLO(arg, "--free-fill", MC_(clo_free_fill), 0x00,0xFF) {}
else
return VG_(replacement_malloc_process_cmd_line_option)(arg);
return True;
- /*NOTREACHED*/
-
- mc_level_error:
- VG_(message)(Vg_DebugMsg, "ERROR: --track-origins=yes has no effect "
- "when --undef-value-errors=no");
- return False;
}
static void mc_print_usage(void)