1*6881a400Schristos /* Everything about exec catchpoints, for GDB. 2*6881a400Schristos 3*6881a400Schristos Copyright (C) 1986-2023 Free Software Foundation, Inc. 4*6881a400Schristos 5*6881a400Schristos This file is part of GDB. 6*6881a400Schristos 7*6881a400Schristos This program is free software; you can redistribute it and/or modify 8*6881a400Schristos it under the terms of the GNU General Public License as published by 9*6881a400Schristos the Free Software Foundation; either version 3 of the License, or 10*6881a400Schristos (at your option) any later version. 11*6881a400Schristos 12*6881a400Schristos This program is distributed in the hope that it will be useful, 13*6881a400Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14*6881a400Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*6881a400Schristos GNU General Public License for more details. 16*6881a400Schristos 17*6881a400Schristos You should have received a copy of the GNU General Public License 18*6881a400Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19*6881a400Schristos 20*6881a400Schristos #include "defs.h" 21*6881a400Schristos 22*6881a400Schristos #include "annotate.h" 23*6881a400Schristos #include "arch-utils.h" 24*6881a400Schristos #include "breakpoint.h" 25*6881a400Schristos #include "cli/cli-decode.h" 26*6881a400Schristos #include "inferior.h" 27*6881a400Schristos #include "mi/mi-common.h" 28*6881a400Schristos #include "target.h" 29*6881a400Schristos #include "valprint.h" 30*6881a400Schristos 31*6881a400Schristos /* Exec catchpoints. */ 32*6881a400Schristos 33*6881a400Schristos /* An instance of this type is used to represent an exec catchpoint. 34*6881a400Schristos A breakpoint is really of this type iff its ops pointer points to 35*6881a400Schristos CATCH_EXEC_BREAKPOINT_OPS. */ 36*6881a400Schristos 37*6881a400Schristos struct exec_catchpoint : public catchpoint 38*6881a400Schristos { 39*6881a400Schristos exec_catchpoint (struct gdbarch *gdbarch, bool temp, const char *cond_string) 40*6881a400Schristos : catchpoint (gdbarch, temp, cond_string) 41*6881a400Schristos { 42*6881a400Schristos } 43*6881a400Schristos 44*6881a400Schristos int insert_location (struct bp_location *) override; 45*6881a400Schristos int remove_location (struct bp_location *, 46*6881a400Schristos enum remove_bp_reason reason) override; 47*6881a400Schristos int breakpoint_hit (const struct bp_location *bl, 48*6881a400Schristos const address_space *aspace, 49*6881a400Schristos CORE_ADDR bp_addr, 50*6881a400Schristos const target_waitstatus &ws) override; 51*6881a400Schristos enum print_stop_action print_it (const bpstat *bs) const override; 52*6881a400Schristos bool print_one (bp_location **) const override; 53*6881a400Schristos void print_mention () const override; 54*6881a400Schristos void print_recreate (struct ui_file *fp) const override; 55*6881a400Schristos 56*6881a400Schristos /* Filename of a program whose exec triggered this catchpoint. 57*6881a400Schristos This field is only valid immediately after this catchpoint has 58*6881a400Schristos triggered. */ 59*6881a400Schristos gdb::unique_xmalloc_ptr<char> exec_pathname; 60*6881a400Schristos }; 61*6881a400Schristos 62*6881a400Schristos int 63*6881a400Schristos exec_catchpoint::insert_location (struct bp_location *bl) 64*6881a400Schristos { 65*6881a400Schristos return target_insert_exec_catchpoint (inferior_ptid.pid ()); 66*6881a400Schristos } 67*6881a400Schristos 68*6881a400Schristos int 69*6881a400Schristos exec_catchpoint::remove_location (struct bp_location *bl, 70*6881a400Schristos enum remove_bp_reason reason) 71*6881a400Schristos { 72*6881a400Schristos return target_remove_exec_catchpoint (inferior_ptid.pid ()); 73*6881a400Schristos } 74*6881a400Schristos 75*6881a400Schristos int 76*6881a400Schristos exec_catchpoint::breakpoint_hit (const struct bp_location *bl, 77*6881a400Schristos const address_space *aspace, 78*6881a400Schristos CORE_ADDR bp_addr, 79*6881a400Schristos const target_waitstatus &ws) 80*6881a400Schristos { 81*6881a400Schristos if (ws.kind () != TARGET_WAITKIND_EXECD) 82*6881a400Schristos return 0; 83*6881a400Schristos 84*6881a400Schristos exec_pathname = make_unique_xstrdup (ws.execd_pathname ()); 85*6881a400Schristos return 1; 86*6881a400Schristos } 87*6881a400Schristos 88*6881a400Schristos enum print_stop_action 89*6881a400Schristos exec_catchpoint::print_it (const bpstat *bs) const 90*6881a400Schristos { 91*6881a400Schristos struct ui_out *uiout = current_uiout; 92*6881a400Schristos 93*6881a400Schristos annotate_catchpoint (number); 94*6881a400Schristos maybe_print_thread_hit_breakpoint (uiout); 95*6881a400Schristos if (disposition == disp_del) 96*6881a400Schristos uiout->text ("Temporary catchpoint "); 97*6881a400Schristos else 98*6881a400Schristos uiout->text ("Catchpoint "); 99*6881a400Schristos if (uiout->is_mi_like_p ()) 100*6881a400Schristos { 101*6881a400Schristos uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXEC)); 102*6881a400Schristos uiout->field_string ("disp", bpdisp_text (disposition)); 103*6881a400Schristos } 104*6881a400Schristos uiout->field_signed ("bkptno", number); 105*6881a400Schristos uiout->text (" (exec'd "); 106*6881a400Schristos uiout->field_string ("new-exec", exec_pathname.get ()); 107*6881a400Schristos uiout->text ("), "); 108*6881a400Schristos 109*6881a400Schristos return PRINT_SRC_AND_LOC; 110*6881a400Schristos } 111*6881a400Schristos 112*6881a400Schristos bool 113*6881a400Schristos exec_catchpoint::print_one (bp_location **last_loc) const 114*6881a400Schristos { 115*6881a400Schristos struct value_print_options opts; 116*6881a400Schristos struct ui_out *uiout = current_uiout; 117*6881a400Schristos 118*6881a400Schristos get_user_print_options (&opts); 119*6881a400Schristos 120*6881a400Schristos /* Field 4, the address, is omitted (which makes the columns 121*6881a400Schristos not line up too nicely with the headers, but the effect 122*6881a400Schristos is relatively readable). */ 123*6881a400Schristos if (opts.addressprint) 124*6881a400Schristos uiout->field_skip ("addr"); 125*6881a400Schristos annotate_field (5); 126*6881a400Schristos uiout->text ("exec"); 127*6881a400Schristos if (exec_pathname != NULL) 128*6881a400Schristos { 129*6881a400Schristos uiout->text (", program \""); 130*6881a400Schristos uiout->field_string ("what", exec_pathname.get ()); 131*6881a400Schristos uiout->text ("\" "); 132*6881a400Schristos } 133*6881a400Schristos 134*6881a400Schristos if (uiout->is_mi_like_p ()) 135*6881a400Schristos uiout->field_string ("catch-type", "exec"); 136*6881a400Schristos 137*6881a400Schristos return true; 138*6881a400Schristos } 139*6881a400Schristos 140*6881a400Schristos void 141*6881a400Schristos exec_catchpoint::print_mention () const 142*6881a400Schristos { 143*6881a400Schristos gdb_printf (_("Catchpoint %d (exec)"), number); 144*6881a400Schristos } 145*6881a400Schristos 146*6881a400Schristos /* Implement the "print_recreate" method for exec catchpoints. */ 147*6881a400Schristos 148*6881a400Schristos void 149*6881a400Schristos exec_catchpoint::print_recreate (struct ui_file *fp) const 150*6881a400Schristos { 151*6881a400Schristos gdb_printf (fp, "catch exec"); 152*6881a400Schristos print_recreate_thread (fp); 153*6881a400Schristos } 154*6881a400Schristos 155*6881a400Schristos /* This function attempts to parse an optional "if <cond>" clause 156*6881a400Schristos from the arg string. If one is not found, it returns NULL. 157*6881a400Schristos 158*6881a400Schristos Else, it returns a pointer to the condition string. (It does not 159*6881a400Schristos attempt to evaluate the string against a particular block.) And, 160*6881a400Schristos it updates arg to point to the first character following the parsed 161*6881a400Schristos if clause in the arg string. */ 162*6881a400Schristos 163*6881a400Schristos const char * 164*6881a400Schristos ep_parse_optional_if_clause (const char **arg) 165*6881a400Schristos { 166*6881a400Schristos const char *cond_string; 167*6881a400Schristos 168*6881a400Schristos if (((*arg)[0] != 'i') || ((*arg)[1] != 'f') || !isspace ((*arg)[2])) 169*6881a400Schristos return NULL; 170*6881a400Schristos 171*6881a400Schristos /* Skip the "if" keyword. */ 172*6881a400Schristos (*arg) += 2; 173*6881a400Schristos 174*6881a400Schristos /* Skip any extra leading whitespace, and record the start of the 175*6881a400Schristos condition string. */ 176*6881a400Schristos *arg = skip_spaces (*arg); 177*6881a400Schristos cond_string = *arg; 178*6881a400Schristos 179*6881a400Schristos /* Assume that the condition occupies the remainder of the arg 180*6881a400Schristos string. */ 181*6881a400Schristos (*arg) += strlen (cond_string); 182*6881a400Schristos 183*6881a400Schristos return cond_string; 184*6881a400Schristos } 185*6881a400Schristos 186*6881a400Schristos /* Commands to deal with catching events, such as signals, exceptions, 187*6881a400Schristos process start/exit, etc. */ 188*6881a400Schristos 189*6881a400Schristos static void 190*6881a400Schristos catch_exec_command_1 (const char *arg, int from_tty, 191*6881a400Schristos struct cmd_list_element *command) 192*6881a400Schristos { 193*6881a400Schristos struct gdbarch *gdbarch = get_current_arch (); 194*6881a400Schristos const char *cond_string = NULL; 195*6881a400Schristos bool temp = command->context () == CATCH_TEMPORARY; 196*6881a400Schristos 197*6881a400Schristos if (!arg) 198*6881a400Schristos arg = ""; 199*6881a400Schristos arg = skip_spaces (arg); 200*6881a400Schristos 201*6881a400Schristos /* The allowed syntax is: 202*6881a400Schristos catch exec 203*6881a400Schristos catch exec if <cond> 204*6881a400Schristos 205*6881a400Schristos First, check if there's an if clause. */ 206*6881a400Schristos cond_string = ep_parse_optional_if_clause (&arg); 207*6881a400Schristos 208*6881a400Schristos if ((*arg != '\0') && !isspace (*arg)) 209*6881a400Schristos error (_("Junk at end of arguments.")); 210*6881a400Schristos 211*6881a400Schristos std::unique_ptr<exec_catchpoint> c 212*6881a400Schristos (new exec_catchpoint (gdbarch, temp, cond_string)); 213*6881a400Schristos 214*6881a400Schristos install_breakpoint (0, std::move (c), 1); 215*6881a400Schristos } 216*6881a400Schristos 217*6881a400Schristos void _initialize_break_catch_exec (); 218*6881a400Schristos void 219*6881a400Schristos _initialize_break_catch_exec () 220*6881a400Schristos { 221*6881a400Schristos add_catch_command ("exec", _("Catch calls to exec."), 222*6881a400Schristos catch_exec_command_1, 223*6881a400Schristos NULL, 224*6881a400Schristos CATCH_PERMANENT, 225*6881a400Schristos CATCH_TEMPORARY); 226*6881a400Schristos } 227