sewardj | 3282402 | 2005-05-17 13:45:04 +0000 | [diff] [blame] | 1 | |
| 2 | /*--------------------------------------------------------------------*/ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 3 | /*--- Command line options. m_options.c ---*/ |
sewardj | 3282402 | 2005-05-17 13:45:04 +0000 | [diff] [blame] | 4 | /*--------------------------------------------------------------------*/ |
| 5 | |
| 6 | /* |
| 7 | This file is part of Valgrind, a dynamic binary instrumentation |
| 8 | framework. |
| 9 | |
sewardj | 03f8d3f | 2012-08-05 15:46:46 +0000 | [diff] [blame] | 10 | Copyright (C) 2000-2012 Nicholas Nethercote |
sewardj | 3282402 | 2005-05-17 13:45:04 +0000 | [diff] [blame] | 11 | njn@valgrind.org |
| 12 | |
| 13 | This program is free software; you can redistribute it and/or |
| 14 | modify it under the terms of the GNU General Public License as |
| 15 | published by the Free Software Foundation; either version 2 of the |
| 16 | License, or (at your option) any later version. |
| 17 | |
| 18 | This program is distributed in the hope that it will be useful, but |
| 19 | WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 21 | General Public License for more details. |
| 22 | |
| 23 | You should have received a copy of the GNU General Public License |
| 24 | along with this program; if not, write to the Free Software |
| 25 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 26 | 02111-1307, USA. |
| 27 | |
| 28 | The GNU General Public License is contained in the file COPYING. |
| 29 | */ |
| 30 | |
njn | c7561b9 | 2005-06-19 01:24:32 +0000 | [diff] [blame] | 31 | #include "pub_core_basics.h" |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 32 | #include "pub_core_vki.h" |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 33 | #include "pub_core_options.h" |
sewardj | 6893d65 | 2006-10-15 01:25:13 +0000 | [diff] [blame] | 34 | #include "pub_core_libcassert.h" |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 35 | #include "pub_core_libcbase.h" |
| 36 | #include "pub_core_libcfile.h" |
sewardj | 6893d65 | 2006-10-15 01:25:13 +0000 | [diff] [blame] | 37 | #include "pub_core_libcprint.h" |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 38 | #include "pub_core_libcproc.h" |
| 39 | #include "pub_core_mallocfree.h" |
sewardj | 0642127 | 2009-11-05 08:55:13 +0000 | [diff] [blame] | 40 | #include "pub_core_seqmatch.h" // VG_(string_match) |
sewardj | 3282402 | 2005-05-17 13:45:04 +0000 | [diff] [blame] | 41 | |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 42 | // See pub_{core,tool}_options.h for explanations of all these. |
| 43 | |
| 44 | |
| 45 | /* Define, and set defaults. */ |
| 46 | VexControl VG_(clo_vex_control); |
| 47 | Bool VG_(clo_error_limit) = True; |
sewardj | b977908 | 2006-05-12 23:50:15 +0000 | [diff] [blame] | 48 | Int VG_(clo_error_exitcode) = 0; |
sewardj | 0ba37c9 | 2011-07-12 11:46:24 +0000 | [diff] [blame] | 49 | |
philippe | 5d5dd8e | 2012-08-05 00:08:25 +0000 | [diff] [blame] | 50 | #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) |
sewardj | deddfdf | 2011-10-26 15:07:56 +0000 | [diff] [blame] | 51 | VgVgdb VG_(clo_vgdb) = Vg_VgdbNo; // currently disabled on Android |
| 52 | #else |
sewardj | 0ba37c9 | 2011-07-12 11:46:24 +0000 | [diff] [blame] | 53 | VgVgdb VG_(clo_vgdb) = Vg_VgdbYes; |
sewardj | deddfdf | 2011-10-26 15:07:56 +0000 | [diff] [blame] | 54 | #endif |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 55 | Int VG_(clo_vgdb_poll) = 5000; |
| 56 | Int VG_(clo_vgdb_error) = 999999999; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 57 | const HChar* VG_(clo_vgdb_prefix) = NULL; |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 58 | Bool VG_(clo_vgdb_shadow_registers) = False; |
sewardj | 0ba37c9 | 2011-07-12 11:46:24 +0000 | [diff] [blame] | 59 | |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 60 | Bool VG_(clo_db_attach) = False; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 61 | const HChar* VG_(clo_db_command) = GDB_PATH " -nw %f %p"; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 62 | Int VG_(clo_gen_suppressions) = 0; |
| 63 | Int VG_(clo_sanity_level) = 1; |
| 64 | Int VG_(clo_verbosity) = 1; |
sewardj | 2d9e874 | 2009-08-07 15:46:56 +0000 | [diff] [blame] | 65 | Bool VG_(clo_stats) = False; |
sewardj | 71bc3cb | 2005-05-19 00:25:45 +0000 | [diff] [blame] | 66 | Bool VG_(clo_xml) = False; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 67 | const HChar* VG_(clo_xml_user_comment) = NULL; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 68 | Bool VG_(clo_demangle) = True; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 69 | const HChar* VG_(clo_soname_synonyms) = NULL; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 70 | Bool VG_(clo_trace_children) = False; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 71 | const HChar* VG_(clo_trace_children_skip) = NULL; |
| 72 | const HChar* VG_(clo_trace_children_skip_by_arg) = NULL; |
sewardj | 6e31f80 | 2007-11-17 22:29:25 +0000 | [diff] [blame] | 73 | Bool VG_(clo_child_silent_after_fork) = False; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 74 | HChar* VG_(clo_log_fname_expanded) = NULL; |
| 75 | HChar* VG_(clo_xml_fname_expanded) = NULL; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 76 | Bool VG_(clo_time_stamp) = False; |
| 77 | Int VG_(clo_input_fd) = 0; /* stdin */ |
| 78 | Int VG_(clo_n_suppressions) = 0; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 79 | const HChar* VG_(clo_suppressions)[VG_CLO_MAX_SFILES]; |
sewardj | 14cdbf8 | 2010-10-12 00:44:05 +0000 | [diff] [blame] | 80 | Int VG_(clo_n_fullpath_after) = 0; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 81 | const HChar* VG_(clo_fullpath_after)[VG_CLO_MAX_FULLPATH_AFTER]; |
sewardj | 71826f7 | 2012-12-06 18:23:20 +0000 | [diff] [blame] | 82 | const HChar* VG_(clo_extra_debuginfo_path) = NULL; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 83 | UChar VG_(clo_trace_flags) = 0; // 00000000b |
| 84 | UChar VG_(clo_profile_flags) = 0; // 00000000b |
florian | 29e022d | 2012-07-02 21:13:34 +0000 | [diff] [blame] | 85 | Int VG_(clo_trace_notbelow) = -1; // unspecified |
| 86 | Int VG_(clo_trace_notabove) = -1; // unspecified |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 87 | Bool VG_(clo_trace_syscalls) = False; |
| 88 | Bool VG_(clo_trace_signals) = False; |
| 89 | Bool VG_(clo_trace_symtab) = False; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 90 | const HChar* VG_(clo_trace_symtab_patt) = "*"; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 91 | Bool VG_(clo_trace_cfi) = False; |
sewardj | f767d96 | 2007-02-12 17:47:14 +0000 | [diff] [blame] | 92 | Bool VG_(clo_debug_dump_syms) = False; |
| 93 | Bool VG_(clo_debug_dump_line) = False; |
| 94 | Bool VG_(clo_debug_dump_frames) = False; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 95 | Bool VG_(clo_trace_redir) = False; |
bart | 78bfc71 | 2011-12-08 16:14:59 +0000 | [diff] [blame] | 96 | enum FairSchedType |
| 97 | VG_(clo_fair_sched) = disable_fair_sched; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 98 | Bool VG_(clo_trace_sched) = False; |
sewardj | 9c606bd | 2008-09-18 18:12:50 +0000 | [diff] [blame] | 99 | Bool VG_(clo_profile_heap) = False; |
philippe | d99c26a | 2012-07-31 22:17:28 +0000 | [diff] [blame] | 100 | Int VG_(clo_core_redzone_size) = CORE_REDZONE_DEFAULT_SZB; |
| 101 | // A value != -1 overrides the tool-specific value |
| 102 | // VG_(needs_malloc_replacement).tool_client_redzone_szB |
| 103 | Int VG_(clo_redzone_size) = -1; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 104 | Int VG_(clo_dump_error) = 0; |
| 105 | Int VG_(clo_backtrace_size) = 12; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 106 | const HChar* VG_(clo_sim_hints) = NULL; |
sewardj | 41ded2c | 2006-10-17 01:34:57 +0000 | [diff] [blame] | 107 | Bool VG_(clo_sym_offsets) = False; |
sewardj | b8b79ad | 2008-03-03 01:35:41 +0000 | [diff] [blame] | 108 | Bool VG_(clo_read_var_info) = False; |
sewardj | f9ebc39 | 2010-05-09 22:30:43 +0000 | [diff] [blame] | 109 | Int VG_(clo_n_req_tsyms) = 0; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 110 | const HChar* VG_(clo_req_tsyms)[VG_CLO_MAX_REQ_TSYMS]; |
sewardj | f9ebc39 | 2010-05-09 22:30:43 +0000 | [diff] [blame] | 111 | HChar* VG_(clo_require_text_symbol) = NULL; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 112 | Bool VG_(clo_run_libc_freeres) = True; |
| 113 | Bool VG_(clo_track_fds) = False; |
| 114 | Bool VG_(clo_show_below_main)= False; |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 115 | Bool VG_(clo_show_emwarns) = False; |
sewardj | 91b470c | 2007-08-28 17:03:01 +0000 | [diff] [blame] | 116 | Word VG_(clo_max_stackframe) = 2000000; |
sewardj | 95d86c0 | 2007-12-18 01:49:23 +0000 | [diff] [blame] | 117 | Word VG_(clo_main_stacksize) = 0; /* use client's rlimit.stack */ |
njn | a3506d3 | 2005-05-18 04:36:01 +0000 | [diff] [blame] | 118 | Bool VG_(clo_wait_for_gdb) = False; |
sewardj | 6c3a219 | 2005-07-24 07:00:45 +0000 | [diff] [blame] | 119 | VgSmc VG_(clo_smc_check) = Vg_SmcStack; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 120 | const HChar* VG_(clo_kernel_variant) = NULL; |
njn | 97db761 | 2009-08-04 02:32:55 +0000 | [diff] [blame] | 121 | Bool VG_(clo_dsymutil) = False; |
sewardj | c30cd9b | 2012-12-06 18:08:54 +0000 | [diff] [blame] | 122 | Bool VG_(clo_sigill_diag) = True; |
sewardj | 3282402 | 2005-05-17 13:45:04 +0000 | [diff] [blame] | 123 | |
sewardj | 6893d65 | 2006-10-15 01:25:13 +0000 | [diff] [blame] | 124 | /*====================================================================*/ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 125 | /*=== File expansion ===*/ |
sewardj | 6893d65 | 2006-10-15 01:25:13 +0000 | [diff] [blame] | 126 | /*====================================================================*/ |
| 127 | |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 128 | // Copies the string, prepending it with the startup working directory, and |
| 129 | // expanding %p and %q entries. Returns a new, malloc'd string. |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 130 | HChar* VG_(expand_file_name)(const HChar* option_name, const HChar* format) |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 131 | { |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 132 | static HChar base_dir[VKI_PATH_MAX]; |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 133 | Int len, i = 0, j = 0; |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 134 | HChar* out; |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 135 | |
| 136 | Bool ok = VG_(get_startup_wd)(base_dir, VKI_PATH_MAX); |
| 137 | tl_assert(ok); |
| 138 | |
| 139 | if (VG_STREQ(format, "")) { |
| 140 | // Empty name, bad. |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 141 | VG_(fmsg)("%s: filename is empty", option_name); |
njn | 5542d8f | 2009-06-09 00:50:45 +0000 | [diff] [blame] | 142 | goto bad; |
| 143 | } |
| 144 | |
| 145 | // If 'format' starts with a '~', abort -- the user probably expected the |
| 146 | // shell to expand but it didn't (see bug 195268 for details). This means |
| 147 | // that we don't allow a legitimate filename beginning with '~' but that |
| 148 | // seems very unlikely. |
| 149 | if (format[0] == '~') { |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 150 | VG_(fmsg)( |
| 151 | "%s: filename begins with '~'\n" |
| 152 | "You probably expected the shell to expand the '~', but it\n" |
| 153 | "didn't. The rules for '~'-expansion vary from shell to shell.\n" |
| 154 | "You might have more luck using $HOME instead.\n", |
| 155 | option_name |
| 156 | ); |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 157 | goto bad; |
| 158 | } |
| 159 | |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 160 | // If 'format' starts with a '/', do not prefix with startup dir. |
| 161 | if (format[0] != '/') { |
| 162 | j += VG_(strlen)(base_dir); |
| 163 | } |
| 164 | |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 165 | // The 10 is slop, it should be enough in most cases. |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 166 | len = j + VG_(strlen)(format) + 10; |
sewardj | 9c606bd | 2008-09-18 18:12:50 +0000 | [diff] [blame] | 167 | out = VG_(malloc)( "options.efn.1", len ); |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 168 | if (format[0] != '/') { |
| 169 | VG_(strcpy)(out, base_dir); |
| 170 | out[j++] = '/'; |
| 171 | } |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 172 | |
| 173 | #define ENSURE_THIS_MUCH_SPACE(x) \ |
| 174 | if (j + x >= len) { \ |
| 175 | len += (10 + x); \ |
sewardj | 9c606bd | 2008-09-18 18:12:50 +0000 | [diff] [blame] | 176 | out = VG_(realloc)("options.efn.2(multiple)", out, len); \ |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 177 | } |
| 178 | |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 179 | while (format[i]) { |
| 180 | if (format[i] != '%') { |
| 181 | ENSURE_THIS_MUCH_SPACE(1); |
| 182 | out[j++] = format[i++]; |
| 183 | |
| 184 | } else { |
| 185 | // We saw a '%'. What's next... |
| 186 | i++; |
| 187 | if ('%' == format[i]) { |
| 188 | // Replace '%%' with '%'. |
| 189 | ENSURE_THIS_MUCH_SPACE(1); |
| 190 | out[j++] = format[i++]; |
| 191 | } |
| 192 | else if ('p' == format[i]) { |
| 193 | // Print the PID. Assume that it's not longer than 10 chars -- |
| 194 | // reasonable since 'pid' is an Int (ie. 32 bits). |
| 195 | Int pid = VG_(getpid)(); |
| 196 | ENSURE_THIS_MUCH_SPACE(10); |
| 197 | j += VG_(sprintf)(&out[j], "%d", pid); |
| 198 | i++; |
| 199 | } |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 200 | else if ('q' == format[i]) { |
| 201 | i++; |
| 202 | if ('{' == format[i]) { |
| 203 | // Get the env var name, print its contents. |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 204 | const HChar* qualname; |
| 205 | HChar* qual; |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 206 | i++; |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 207 | qualname = &format[i]; |
| 208 | while (True) { |
| 209 | if (0 == format[i]) { |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 210 | VG_(fmsg)("%s: malformed %%q specifier\n", option_name); |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 211 | goto bad; |
| 212 | } else if ('}' == format[i]) { |
| 213 | // Temporarily replace the '}' with NUL to extract var |
| 214 | // name. |
florian | cfea784 | 2012-10-20 19:52:14 +0000 | [diff] [blame] | 215 | // FIXME: this is not safe as FORMAT is sometimes a |
| 216 | // string literal which may reside in read-only memory |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 217 | ((HChar *)format)[i] = 0; |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 218 | qual = VG_(getenv)(qualname); |
| 219 | if (NULL == qual) { |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 220 | VG_(fmsg)("%s: environment variable %s is not set\n", |
| 221 | option_name, qualname); |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 222 | // FIXME: this is not safe as FORMAT is sometimes a |
| 223 | // string literal which may reside in read-only memory |
| 224 | ((HChar *)format)[i] = '}'; // Put the '}' back. |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 225 | goto bad; |
| 226 | } |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 227 | // FIXME: this is not safe as FORMAT is sometimes a |
| 228 | // string literal which may reside in read-only memory |
| 229 | ((HChar *)format)[i] = '}'; // Put the '}' back. |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 230 | i++; |
| 231 | break; |
| 232 | } |
| 233 | i++; |
| 234 | } |
| 235 | ENSURE_THIS_MUCH_SPACE(VG_(strlen)(qual)); |
| 236 | j += VG_(sprintf)(&out[j], "%s", qual); |
| 237 | } else { |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 238 | VG_(fmsg)("%s: expected '{' after '%%q'\n", option_name); |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 239 | goto bad; |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 240 | } |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 241 | } |
| 242 | else { |
| 243 | // Something else, abort. |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 244 | VG_(fmsg)("%s: expected 'p' or 'q' or '%%' after '%%'\n", |
| 245 | option_name); |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 246 | goto bad; |
| 247 | } |
| 248 | } |
| 249 | } |
| 250 | ENSURE_THIS_MUCH_SPACE(1); |
| 251 | out[j++] = 0; |
| 252 | |
| 253 | return out; |
| 254 | |
| 255 | bad: { |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 256 | HChar* opt = // 2: 1 for the '=', 1 for the NUL. |
sewardj | 9c606bd | 2008-09-18 18:12:50 +0000 | [diff] [blame] | 257 | VG_(malloc)( "options.efn.3", |
| 258 | VG_(strlen)(option_name) + VG_(strlen)(format) + 2 ); |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 259 | VG_(strcpy)(opt, option_name); |
| 260 | VG_(strcat)(opt, "="); |
| 261 | VG_(strcat)(opt, format); |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 262 | VG_(fmsg_bad_option)(opt, ""); |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 263 | } |
| 264 | } |
| 265 | |
sewardj | 0642127 | 2009-11-05 08:55:13 +0000 | [diff] [blame] | 266 | /*====================================================================*/ |
| 267 | /*=== --trace-children= support ===*/ |
| 268 | /*====================================================================*/ |
| 269 | |
| 270 | static HChar const* consume_commas ( HChar const* c ) { |
| 271 | while (*c && *c == ',') { |
| 272 | ++c; |
| 273 | } |
| 274 | return c; |
| 275 | } |
| 276 | |
| 277 | static HChar const* consume_field ( HChar const* c ) { |
| 278 | while (*c && *c != ',') { |
| 279 | ++c; |
| 280 | } |
| 281 | return c; |
| 282 | } |
| 283 | |
| 284 | /* Should we trace into this child executable (across execve etc) ? |
sewardj | 9ab64a4 | 2010-12-06 11:40:04 +0000 | [diff] [blame] | 285 | This involves considering --trace-children=, |
| 286 | --trace-children-skip=, --trace-children-skip-by-arg=, and the name |
| 287 | of the executable. 'child_argv' must not include the name of the |
| 288 | executable itself; iow child_argv[0] must be the first arg, if any, |
| 289 | for the child. */ |
| 290 | Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name, |
| 291 | HChar** child_argv ) |
sewardj | 0642127 | 2009-11-05 08:55:13 +0000 | [diff] [blame] | 292 | { |
| 293 | // child_exe_name is pulled out of the guest's space. We |
| 294 | // should be at least marginally cautious with it, lest it |
| 295 | // explode or burst into flames unexpectedly. |
| 296 | if (child_exe_name == NULL || VG_(strlen)(child_exe_name) == 0) |
| 297 | return VG_(clo_trace_children); // we know narfink |
| 298 | |
sewardj | 0642127 | 2009-11-05 08:55:13 +0000 | [diff] [blame] | 299 | // If --trace-children=no, the answer is simply NO. |
| 300 | if (! VG_(clo_trace_children)) |
| 301 | return False; |
| 302 | |
sewardj | 9ab64a4 | 2010-12-06 11:40:04 +0000 | [diff] [blame] | 303 | // Otherwise, look for other reasons to say NO. First, |
| 304 | // see if the exe name matches any of the patterns specified |
| 305 | // by --trace-children-skip=. |
sewardj | 0642127 | 2009-11-05 08:55:13 +0000 | [diff] [blame] | 306 | if (VG_(clo_trace_children_skip)) { |
| 307 | HChar const* last = VG_(clo_trace_children_skip); |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 308 | HChar const* name = child_exe_name; |
sewardj | 0642127 | 2009-11-05 08:55:13 +0000 | [diff] [blame] | 309 | while (*last) { |
| 310 | Bool matches; |
| 311 | HChar* patt; |
| 312 | HChar const* first = consume_commas(last); |
| 313 | last = consume_field(first); |
| 314 | if (first == last) |
| 315 | break; |
| 316 | vg_assert(last > first); |
| 317 | /* copy the candidate string into a temporary malloc'd block |
| 318 | so we can use VG_(string_match) on it. */ |
| 319 | patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1); |
| 320 | VG_(memcpy)(patt, first, last - first); |
| 321 | vg_assert(patt[last-first] == 0); |
| 322 | matches = VG_(string_match)(patt, name); |
| 323 | VG_(free)(patt); |
| 324 | if (matches) |
| 325 | return False; |
| 326 | } |
| 327 | } |
sewardj | 9ab64a4 | 2010-12-06 11:40:04 +0000 | [diff] [blame] | 328 | |
| 329 | // Check if any of the args match any of the patterns specified |
| 330 | // by --trace-children-skip-by-arg=. |
| 331 | if (VG_(clo_trace_children_skip_by_arg) && child_argv != NULL) { |
| 332 | HChar const* last = VG_(clo_trace_children_skip_by_arg); |
| 333 | while (*last) { |
| 334 | Int i; |
| 335 | Bool matches; |
| 336 | HChar* patt; |
| 337 | HChar const* first = consume_commas(last); |
| 338 | last = consume_field(first); |
| 339 | if (first == last) |
| 340 | break; |
| 341 | vg_assert(last > first); |
| 342 | /* copy the candidate string into a temporary malloc'd block |
| 343 | so we can use VG_(string_match) on it. */ |
| 344 | patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1); |
| 345 | VG_(memcpy)(patt, first, last - first); |
| 346 | vg_assert(patt[last-first] == 0); |
| 347 | for (i = 0; child_argv[i]; i++) { |
| 348 | matches = VG_(string_match)(patt, child_argv[i]); |
| 349 | if (matches) { |
| 350 | VG_(free)(patt); |
| 351 | return False; |
| 352 | } |
| 353 | } |
| 354 | VG_(free)(patt); |
| 355 | } |
| 356 | } |
| 357 | |
sewardj | 0642127 | 2009-11-05 08:55:13 +0000 | [diff] [blame] | 358 | // --trace-children=yes, and this particular executable isn't |
| 359 | // excluded |
| 360 | return True; |
| 361 | } |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 362 | |
sewardj | 6893d65 | 2006-10-15 01:25:13 +0000 | [diff] [blame] | 363 | |
sewardj | 3282402 | 2005-05-17 13:45:04 +0000 | [diff] [blame] | 364 | /*--------------------------------------------------------------------*/ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 365 | /*--- end ---*/ |
sewardj | 3282402 | 2005-05-17 13:45:04 +0000 | [diff] [blame] | 366 | /*--------------------------------------------------------------------*/ |