VexControl VG_(clo_vex_control);
Bool VG_(clo_error_limit) = True;
Int VG_(clo_error_exitcode) = 0;
+#if (VGO_l4re)
+VgVgdb VG_(clo_vgdb) = Vg_VgdbNo;
+#else
+VgVgdb VG_(clo_vgdb) = Vg_VgdbYes;
+#endif
+Int VG_(clo_vgdb_poll) = 5000;
+Int VG_(clo_vgdb_error) = 999999999;
+Char* VG_(clo_vgdb_prefix) = VG_CLO_VGDB_PREFIX_DEFAULT;
+Bool VG_(clo_vgdb_shadow_registers) = False;
Bool VG_(clo_db_attach) = False;
Char* VG_(clo_db_command) = GDB_PATH " -nw %f %p";
Int VG_(clo_gen_suppressions) = 0;
Bool VG_(clo_demangle) = True;
Bool VG_(clo_trace_children) = False;
HChar* VG_(clo_trace_children_skip) = NULL;
+HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
Bool VG_(clo_child_silent_after_fork) = False;
Char* VG_(clo_log_fname_expanded) = NULL;
Char* VG_(clo_xml_fname_expanded) = NULL;
Int VG_(clo_input_fd) = 0; /* stdin */
Int VG_(clo_n_suppressions) = 0;
Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
+Int VG_(clo_n_fullpath_after) = 0;
+Char* VG_(clo_fullpath_after)[VG_CLO_MAX_FULLPATH_AFTER];
UChar VG_(clo_trace_flags) = 0; // 00000000b
UChar VG_(clo_profile_flags) = 0; // 00000000b
Int VG_(clo_trace_notbelow) = 999999999;
}
/* Should we trace into this child executable (across execve etc) ?
- This involves considering --trace-children=, --trace-children-skip=
- and the name of the executable. */
-Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name )
+ This involves considering --trace-children=,
+ --trace-children-skip=, --trace-children-skip-by-arg=, and the name
+ of the executable. 'child_argv' must not include the name of the
+ executable itself; iow child_argv[0] must be the first arg, if any,
+ for the child. */
+Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name,
+ HChar** child_argv )
{
// child_exe_name is pulled out of the guest's space. We
// should be at least marginally cautious with it, lest it
if (child_exe_name == NULL || VG_(strlen)(child_exe_name) == 0)
return VG_(clo_trace_children); // we know narfink
- // the main logic
// If --trace-children=no, the answer is simply NO.
if (! VG_(clo_trace_children))
return False;
- // otherwise, return True, unless the exe name matches any of the
- // patterns specified by --trace-children-skip=.
+ // Otherwise, look for other reasons to say NO. First,
+ // see if the exe name matches any of the patterns specified
+ // by --trace-children-skip=.
if (VG_(clo_trace_children_skip)) {
HChar const* last = VG_(clo_trace_children_skip);
HChar const* name = (HChar const*)child_exe_name;
return False;
}
}
-
+
+ // Check if any of the args match any of the patterns specified
+ // by --trace-children-skip-by-arg=.
+ if (VG_(clo_trace_children_skip_by_arg) && child_argv != NULL) {
+ HChar const* last = VG_(clo_trace_children_skip_by_arg);
+ while (*last) {
+ Int i;
+ Bool matches;
+ HChar* patt;
+ HChar const* first = consume_commas(last);
+ last = consume_field(first);
+ if (first == last)
+ break;
+ vg_assert(last > first);
+ /* copy the candidate string into a temporary malloc'd block
+ so we can use VG_(string_match) on it. */
+ patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
+ VG_(memcpy)(patt, first, last - first);
+ vg_assert(patt[last-first] == 0);
+ for (i = 0; child_argv[i]; i++) {
+ matches = VG_(string_match)(patt, child_argv[i]);
+ if (matches) {
+ VG_(free)(patt);
+ return False;
+ }
+ }
+ VG_(free)(patt);
+ }
+ }
+
// --trace-children=yes, and this particular executable isn't
// excluded
return True;