[PATCH v7 1/3] MI: add the -catch-load and -catch-unload commands

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH v7 1/3] MI: add the -catch-load and -catch-unload commands

Mircea Gherzan-6
They are equivalent to "catch load" and "catch unload" from CLI.

Rationale: GUIs might be interested in catching solib load or
unload events.

2012-11-16  Mircea Gherzan  <[hidden email]>

        * Makefile.in (SUBDIR_MI_OBS): Add mi-cmd-catch.o.
        (SUBDIR_MI_SRCS): Add mi/mi-cmd-catch.c.
        * breakpoint.c (add_solib_catchpoint): New function based on
        that can be used by both CLI and MI, factored out from
        catch_load_or_unload.
        (catch_load_or_unload): Strip it down and make it use the
        new add_solib_catchpoint.
        * breakpoint.h (add_solib_catchpoint): Declare it.
        * mi/mi-cmd-catch.c: New file.
        * mi/mi-cmds.c (mi_cmds): Add the handlers for -catch-load
        and -catch-unload.
        * mi/mi-cmds.h: Declare the handlers for -catch-load and
        -catch-unload.

Signed-off-by: Mircea Gherzan <[hidden email]>
---
 gdb/Makefile.in       |    9 +++-
 gdb/breakpoint.c      |   33 +++++++++----
 gdb/breakpoint.h      |    5 ++
 gdb/mi/mi-cmd-catch.c |  126 +++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c      |    4 ++
 gdb/mi/mi-cmds.h      |    2 +
 6 files changed, 167 insertions(+), 12 deletions(-)
 create mode 100644 gdb/mi/mi-cmd-catch.c

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3dd7b85..40c7e80 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -203,13 +203,14 @@ SUBDIR_CLI_CFLAGS=
 #
 SUBDIR_MI_OBS = \
  mi-out.o mi-console.o \
- mi-cmds.o mi-cmd-env.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
+ mi-cmds.o mi-cmd-catch.o mi-cmd-env.o \
+ mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
  mi-cmd-file.o mi-cmd-disas.o mi-symbol-cmds.o mi-cmd-target.o \
  mi-cmd-info.o mi-interp.o \
  mi-main.o mi-parse.o mi-getopt.o
 SUBDIR_MI_SRCS = \
  mi/mi-out.c mi/mi-console.c \
- mi/mi-cmds.c mi/mi-cmd-env.c \
+ mi/mi-cmds.c mi/mi-cmd-catch.c mi/mi-cmd-env.c \
  mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \
  mi/mi-cmd-file.c mi/mi-cmd-disas.c mi/mi-symbol-cmds.c \
  mi/mi-cmd-target.c mi/mi-cmd-info.c mi/mi-interp.c \
@@ -1833,6 +1834,10 @@ mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c
  $(COMPILE) $(srcdir)/mi/mi-cmd-break.c
  $(POSTCOMPILE)
 
+mi-cmd-catch.o: $(srcdir)/mi/mi-cmd-catch.c
+ $(COMPILE) $(srcdir)/mi/mi-cmd-catch.c
+ $(POSTCOMPILE)
+
 mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c
  $(COMPILE) $(srcdir)/mi/mi-cmd-disas.c
  $(POSTCOMPILE)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 5749fa7..1c95c04 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7847,20 +7847,16 @@ print_recreate_catch_solib (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_solib_breakpoint_ops;
 
-/* A helper function that does all the work for "catch load" and
-   "catch unload".  */
+/* Shared helper function (MI and CLI) for creating and installing
+   a shared object event catchpoint.  */
 
-static void
-catch_load_or_unload (char *arg, int from_tty, int is_load,
-      struct cmd_list_element *command)
+void
+add_solib_catchpoint (char *arg, int is_load, int is_temp, int enabled)
 {
   struct solib_catchpoint *c;
-  struct gdbarch *gdbarch = get_current_arch ();
-  int tempflag;
+  struct gdbarch *arch = get_current_arch ();
   struct cleanup *cleanup;
 
-  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
-
   if (!arg)
     arg = "";
   arg = skip_spaces (arg);
@@ -7884,13 +7880,30 @@ catch_load_or_unload (char *arg, int from_tty, int is_load,
     }
 
   c->is_load = is_load;
-  init_catchpoint (&c->base, gdbarch, tempflag, NULL,
+  init_catchpoint (&c->base, arch, is_temp, NULL,
    &catch_solib_breakpoint_ops);
 
+  c->base.enable_state = enabled ? bp_enabled : bp_disabled;
+
   discard_cleanups (cleanup);
   install_breakpoint (0, &c->base, 1);
 }
 
+/* A helper function that does all the work for "catch load" and
+   "catch unload".  */
+
+static void
+catch_load_or_unload (char *arg, int from_tty, int is_load,
+      struct cmd_list_element *command)
+{
+  int tempflag;
+  const int enabled = 1;
+
+  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+
+  add_solib_catchpoint (arg, is_load, tempflag, enabled);
+}
+
 static void
 catch_load_command_1 (char *arg, int from_tty,
       struct cmd_list_element *command)
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 8b1bcb7..11e432c 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -1405,6 +1405,11 @@ extern void disable_breakpoints_in_shlibs (void);
 /* This function returns TRUE if ep is a catchpoint.  */
 extern int is_catchpoint (struct breakpoint *);
 
+/* Shared helper function (MI and CLI) for creating and installing
+   a shared object event catchpoint.  */
+extern void add_solib_catchpoint (char *arg, int is_load, int is_temp,
+                                  int enabled);
+
 /* Enable breakpoints and delete when hit.  Called with ARG == NULL
    deletes all breakpoints.  */
 extern void delete_command (char *arg, int from_tty);
diff --git a/gdb/mi/mi-cmd-catch.c b/gdb/mi/mi-cmd-catch.c
new file mode 100644
index 0000000..c7b494e
--- /dev/null
+++ b/gdb/mi/mi-cmd-catch.c
@@ -0,0 +1,126 @@
+/* MI Command Set - catch commands.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corporation.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "breakpoint.h"
+#include "gdb.h"
+#include "libiberty.h"
+#include "mi-cmds.h"
+#include "mi-getopt.h"
+#include "observer.h"
+#include "ui-out.h"
+
+/* True if MI breakpoint observers have been registered.  */
+
+static int mi_catchpoint_observers_installed;
+
+/* Control whether breakpoint_notify may act.  */
+
+static int mi_can_catchpoint_notify;
+
+/* Output a single breakpoint, when allowed.  */
+
+static void
+catchpoint_notify (struct breakpoint *b)
+{
+  if (mi_can_catchpoint_notify)
+    gdb_breakpoint_query (current_uiout, b->number, NULL);
+}
+
+/* Common path for the -catch-load and -catch-unload.  */
+
+static void
+mi_catch_load_unload (int load, char *argv[], int argc)
+{
+  struct solib_catchpoint *c;
+  struct cleanup *back_to;
+  char *actual_cmd = load ? "-catch-load" : "-catch-unload";
+  int temp = 0;
+  int enabled = 1;
+  int oind = 0;
+  char *oarg;
+  enum opt
+    {
+      OPT_TEMP,
+      OPT_DISABLED,
+    };
+  static const struct mi_opt opts[] =
+    {
+      { "t", OPT_TEMP, 0 },
+      { "d", OPT_DISABLED, 0 },
+      { 0, 0, 0 }
+    };
+
+  for (;;)
+    {
+      int opt = mi_getopt (actual_cmd, argc, argv, opts,
+                           &oind, &oarg);
+
+      if (opt < 0)
+        break;
+
+      switch ((enum opt) opt)
+        {
+        case OPT_TEMP:
+          temp = 1;
+          break;
+        case OPT_DISABLED:
+          enabled = 0;
+          break;
+        }
+    }
+
+  if (oind >= argc)
+    error (_("-catch-load/unload: Missing <library name>"));
+  if (oind < argc -1)
+    error (_("-catch-load/unload: Garbage following the <library name>"));
+
+  if (! mi_catchpoint_observers_installed)
+    {
+      observer_attach_breakpoint_created (catchpoint_notify);
+      mi_catchpoint_observers_installed = 1;
+    }
+
+  back_to = make_cleanup_restore_integer (&mi_can_catchpoint_notify);
+  mi_can_catchpoint_notify = 1;
+
+  add_solib_catchpoint (argv[oind], load, temp, enabled);
+
+  do_cleanups (back_to);
+}
+
+/* Handler for the -catch-load.  */
+
+void
+mi_cmd_catch_load (char *cmd, char *argv[], int argc)
+{
+  mi_catch_load_unload (1, argv, argc);
+}
+
+
+/* Handler for the -catch-unload.  */
+
+void
+mi_cmd_catch_unload (char *cmd, char *argv[], int argc)
+{
+  mi_catch_load_unload (0, argv, argc);
+}
+
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 572625f..0e3cd6c 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -67,6 +67,10 @@ static struct mi_cmd mi_cmds[] =
    &mi_suppress_notification.breakpoint),
   DEF_MI_CMD_MI_1 ("break-watch", mi_cmd_break_watch,
    &mi_suppress_notification.breakpoint),
+  DEF_MI_CMD_MI_1 ("catch-load", mi_cmd_catch_load,
+                   &mi_suppress_notification.breakpoint),
+  DEF_MI_CMD_MI_1 ("catch-unload", mi_cmd_catch_unload,
+                   &mi_suppress_notification.breakpoint),
   DEF_MI_CMD_MI ("data-disassemble", mi_cmd_disassemble),
   DEF_MI_CMD_MI ("data-evaluate-expression", mi_cmd_data_evaluate_expression),
   DEF_MI_CMD_MI ("data-list-changed-registers",
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index cf1a5eb..da8df48 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -43,6 +43,8 @@ extern mi_cmd_argv_ftype mi_cmd_break_insert;
 extern mi_cmd_argv_ftype mi_cmd_break_commands;
 extern mi_cmd_argv_ftype mi_cmd_break_passcount;
 extern mi_cmd_argv_ftype mi_cmd_break_watch;
+extern mi_cmd_argv_ftype mi_cmd_catch_load;
+extern mi_cmd_argv_ftype mi_cmd_catch_unload;
 extern mi_cmd_argv_ftype mi_cmd_disassemble;
 extern mi_cmd_argv_ftype mi_cmd_data_evaluate_expression;
 extern mi_cmd_argv_ftype mi_cmd_data_list_register_names;
--
1.7.1

Reply | Threaded
Open this post in threaded view
|

[PATCH v7 2/3] MI: document the -catch-load/-unload commands

Mircea Gherzan-6
2012-11-16 Mircea Gherzan <[hidden email]>

gdb/doc:
        * gdb.texinfo (GDB/MI Catchpoint Commands): New section.

gdb/:
        * NEWS: mention the -catch-load/-catch-unload MI commands.

Signed-off-by: Mircea Gherzan <[hidden email]>
---
 gdb/NEWS            |    2 +
 gdb/doc/gdb.texinfo |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 3b09e5f..06ede52 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -99,6 +99,8 @@ show print type typedefs
      has been requested.
   ** New optional parameter COUNT added to the "-data-write-memory-bytes"
      command, to allow pattern filling of memory areas.
+  ** New commands "-catch-load"/"-catch-unload" added for intercepting
+     library load/unload events.
 
 * GDB now supports the "mini debuginfo" section, .gnu_debugdata.
   You must have the LZMA library available when configuring GDB for this
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index afe3845..cadbb34 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -27139,6 +27139,7 @@ may repeat one or more times.
 * GDB/MI Simple Examples::
 * GDB/MI Command Description Format::
 * GDB/MI Breakpoint Commands::
+* GDB/MI Catchpoint Commands::
 * GDB/MI Program Context::
 * GDB/MI Thread Commands::
 * GDB/MI Ada Tasking Commands::
@@ -28713,6 +28714,75 @@ times="1"@}]@}
 (gdb)
 @end smallexample
 
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Catchpoint Commands
+@section @sc{gdb/mi} Catchpoint Commands
+
+This section documents @sc{gdb/mi} commands for manipulating
+catchpoints.
+
+@subheading The @code{-catch-load} Command
+@findex -catch-load
+
+@subsubheading Synopsis
+
+@smallexample
+ -catch-load [ -t ] [ -d ] @var{regexp}
+@end smallexample
+
+Add a catchpoint for library load events.  If the @samp{-t} option is used,
+the catchpoint is a temporary one (@pxref{Set Breaks, ,Setting
+Breakpoints}).  If the @samp{-d} option is used, the catchpoint is created
+in a disabled state.  The @samp{regexp} argument is a regular
+expression used to match the name of the loaded library.
+
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{catch load}.
+
+@subsubheading Example
+
+@smallexample
+-catch-load -t foo.so
+=breakpoint-created,bkpt=@{number="1",type="catchpoint",disp="del",
+enabled="y",what="load of library matching foo.so",times="0"@}
+^done
+(gdb)
+@end smallexample
+
+
+@subheading The @code{-catch-unload} Command
+@findex -catch-unload
+
+@subsubheading Synopsis
+
+@smallexample
+ -catch-unload [ -t ] [ -d ] @var{regexp}
+@end smallexample
+
+Add a catchpoint for library unload events.  If the @samp{-t} option is
+used, the catchpoint is a temporary one (@pxref{Set Breaks, ,Setting
+Breakpoints}).  If the @samp{-d} option is used, the catchpoint is
+created in a disabled state.  The @samp{regexp} argument is a regular
+expression used to match the name of the unloaded library.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{catch unload}.
+
+@subsubheading Example
+
+@smallexample
+-catch-unload -d bar.so
+=breakpoint-created,bkpt=@{number="1",type="catchpoint",disp="keep",
+enabled="n",what="unload of library matching bar.so",times="0"@}
+^done
+(gdb)
+@end smallexample
+
+
 @c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 @node GDB/MI Program Context
 @section @sc{gdb/mi}  Program Context
--
1.7.1

Reply | Threaded
Open this post in threaded view
|

[PATCH v7 3/3] MI: tests for -catch-load/-catch-unload

Mircea Gherzan-6
In reply to this post by Mircea Gherzan-6
From: Keven Boell <[hidden email]>

Added basic MI tests for the -catch-load and
-catch-unload MI commands.

2012-11-19 Keven Boell <[hidden email]>

gdb/testsuite:
        * gdb.mi/mi-catch-load-so.c: New. Clone of the
        catch load test library source file.
        * gdb.mi/mi-catch-load.c: New. Clone of the catch
        load test source file.
        * gdb.mi/mi-catch-load.exp: New. Test file for
        basic MI -catch-load and -catch-unload tests.

Signed-off-by: Keven Boell <[hidden email]>
---
 gdb/testsuite/gdb.mi/mi-catch-load-so.c |   22 +++++++
 gdb/testsuite/gdb.mi/mi-catch-load.c    |   33 +++++++++++
 gdb/testsuite/gdb.mi/mi-catch-load.exp  |   93 +++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+), 0 deletions(-)
 create mode 100644 gdb/testsuite/gdb.mi/mi-catch-load-so.c
 create mode 100644 gdb/testsuite/gdb.mi/mi-catch-load.c
 create mode 100644 gdb/testsuite/gdb.mi/mi-catch-load.exp

diff --git a/gdb/testsuite/gdb.mi/mi-catch-load-so.c b/gdb/testsuite/gdb.mi/mi-catch-load-so.c
new file mode 100644
index 0000000..8c3d0d6
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-catch-load-so.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+f (void)
+{
+  return 23;
+}
diff --git a/gdb/testsuite/gdb.mi/mi-catch-load.c b/gdb/testsuite/gdb.mi/mi-catch-load.c
new file mode 100644
index 0000000..0035c88
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-catch-load.c
@@ -0,0 +1,33 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+char *libname = "mi-catch-load-so.so";
+
+int
+main ()
+{
+  void *h;
+
+  h = dlopen (libname, RTLD_LAZY);
+
+  dlclose (h);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.mi/mi-catch-load.exp b/gdb/testsuite/gdb.mi/mi-catch-load.exp
new file mode 100644
index 0000000..9d6136f
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-catch-load.exp
@@ -0,0 +1,93 @@
+# Copyright 2012 Free Software Foundation, Inc.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+load_lib mi-support.exp
+
+if {[skip_shlib_tests]} {
+    return -1
+}
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+if {[get_compiler_info]} {
+    warning "Could not get compiler info"
+    untested mi-catch-load.exp
+    return -1
+}
+
+standard_testfile mi-catch-load.c
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug shlib_load}] != "" } {
+    untested mi-catch-load.exp
+    return -1
+}
+
+set testfile2 mi-catch-load-so
+set srcfile2 ${testfile2}.c
+set binfile2 ${objdir}/${subdir}/${testfile2}.so
+set binfile2_dlopen [shlib_target_file ${testfile2}.so]
+if { [gdb_compile_shlib "${srcdir}/${subdir}/${srcfile2}" ${binfile2} {debug}] != "" } {
+    untested mi-catch-load.exp
+    return -1
+}
+mi_run_to_main
+
+# test -catch-load
+mi_gdb_test "111-gdb-set auto-solib-add on" "111\\^done" "catch-load: auto-solib-add on"
+mi_gdb_test "222-catch-load -t mi-catch-load-so.so" \
+    "222\\^done,bkpt=\{number=\"2\",type=\"catchpoint\",disp=\"del\",enabled=\"y\",what=\"load of library matching mi-catch-load-so\.so\",times=\"0\"\}" \
+    "catch-load: catch load"
+mi_send_resuming_command "exec-continue" "catch-load: continue"
+
+gdb_expect {
+    -re "\\*stopped.*reason=\"solib-event\".*added=.*\r\n.*\r\n$mi_gdb_prompt$" {
+        pass "catch-load: solib-event stop"
+    }
+    -re ".*$mi_gdb_prompt$" {
+        fail "catch-load: solib-event stop"
+    }
+    timeout {
+        fail "(timeout) catch-load: solib-event stop"
+    }
+}
+
+mi_gdb_exit
+
+
+if [mi_gdb_start] {
+    continue
+}
+mi_run_to_main
+
+# test -catch-unload
+mi_gdb_test "111-gdb-set auto-solib-add on" "111\\^done" "catch-unload: auto-solib-add on"
+mi_gdb_test "222-catch-unload -t mi-catch-load-so.so" \
+    "222\\^done,bkpt=\{number=\"2\",type=\"catchpoint\",disp=\"del\",enabled=\"y\",what=\"unload of library matching mi-catch-load-so\.so\",times=\"0\"\}" \
+    "catch-unload: catch unload"
+mi_send_resuming_command "exec-continue" "catch-unload: continue"
+
+gdb_expect {
+    -re "\\*stopped.*reason=\"solib-event\".*removed=.*\r\n.*\r\n$mi_gdb_prompt$" {
+        pass "catch-unload: solib-event stop"
+    }
+    -re ".*$mi_gdb_prompt$" {
+        fail "catch-unload: solib-event stop"
+    }
+    timeout {
+        fail "(timeout) catch-unload: solib-event stop"
+    }
+}
--
1.7.1

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v7 1/3] MI: add the -catch-load and -catch-unload commands

Vladimir Prus-3
In reply to this post by Mircea Gherzan-6
On 29.11.2012 03:05, Mircea Gherzan wrote:

> They are equivalent to "catch load" and "catch unload" from CLI.
>
> Rationale: GUIs might be interested in catching solib load or
> unload events.
>
> 2012-11-16  Mircea Gherzan<[hidden email]>
>
> * Makefile.in (SUBDIR_MI_OBS): Add mi-cmd-catch.o.
> (SUBDIR_MI_SRCS): Add mi/mi-cmd-catch.c.
> * breakpoint.c (add_solib_catchpoint): New function based on
> that can be used by both CLI and MI, factored out from
> catch_load_or_unload.
> (catch_load_or_unload): Strip it down and make it use the
> new add_solib_catchpoint.
> * breakpoint.h (add_solib_catchpoint): Declare it.
> * mi/mi-cmd-catch.c: New file.
> * mi/mi-cmds.c (mi_cmds): Add the handlers for -catch-load
> and -catch-unload.
> * mi/mi-cmds.h: Declare the handlers for -catch-load and
> -catch-unload.
>
> Signed-off-by: Mircea Gherzan<[hidden email]>
> ---
>   gdb/Makefile.in       |    9 +++-
>   gdb/breakpoint.c      |   33 +++++++++----
>   gdb/breakpoint.h      |    5 ++
>   gdb/mi/mi-cmd-catch.c |  126 +++++++++++++++++++++++++++++++++++++++++++++++++
>   gdb/mi/mi-cmds.c      |    4 ++
>   gdb/mi/mi-cmds.h      |    2 +
>   6 files changed, 167 insertions(+), 12 deletions(-)
>   create mode 100644 gdb/mi/mi-cmd-catch.c
>
> diff --git a/gdb/Makefile.in b/gdb/Makefile.in
> index 3dd7b85..40c7e80 100644
> --- a/gdb/Makefile.in
> +++ b/gdb/Makefile.in
> @@ -203,13 +203,14 @@ SUBDIR_CLI_CFLAGS=
>   #
>   SUBDIR_MI_OBS = \
>   mi-out.o mi-console.o \
> - mi-cmds.o mi-cmd-env.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
> + mi-cmds.o mi-cmd-catch.o mi-cmd-env.o \
> + mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \
>   mi-cmd-file.o mi-cmd-disas.o mi-symbol-cmds.o mi-cmd-target.o \
>   mi-cmd-info.o mi-interp.o \
>   mi-main.o mi-parse.o mi-getopt.o
>   SUBDIR_MI_SRCS = \
>   mi/mi-out.c mi/mi-console.c \
> - mi/mi-cmds.c mi/mi-cmd-env.c \
> + mi/mi-cmds.c mi/mi-cmd-catch.c mi/mi-cmd-env.c \
>   mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \
>   mi/mi-cmd-file.c mi/mi-cmd-disas.c mi/mi-symbol-cmds.c \
>   mi/mi-cmd-target.c mi/mi-cmd-info.c mi/mi-interp.c \
> @@ -1833,6 +1834,10 @@ mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c
>   $(COMPILE) $(srcdir)/mi/mi-cmd-break.c
>   $(POSTCOMPILE)
>
> +mi-cmd-catch.o: $(srcdir)/mi/mi-cmd-catch.c
> + $(COMPILE) $(srcdir)/mi/mi-cmd-catch.c
> + $(POSTCOMPILE)
> +
>   mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c
>   $(COMPILE) $(srcdir)/mi/mi-cmd-disas.c
>   $(POSTCOMPILE)
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index 5749fa7..1c95c04 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -7847,20 +7847,16 @@ print_recreate_catch_solib (struct breakpoint *b, struct ui_file *fp)
>
>   static struct breakpoint_ops catch_solib_breakpoint_ops;
>
> -/* A helper function that does all the work for "catch load" and
> -   "catch unload".  */
> +/* Shared helper function (MI and CLI) for creating and installing
> +   a shared object event catchpoint.  */
>
> -static void
> -catch_load_or_unload (char *arg, int from_tty, int is_load,
> -      struct cmd_list_element *command)
> +void
> +add_solib_catchpoint (char *arg, int is_load, int is_temp, int enabled)
>   {
>     struct solib_catchpoint *c;
> -  struct gdbarch *gdbarch = get_current_arch ();
> -  int tempflag;
> +  struct gdbarch *arch = get_current_arch ();

Is gdbarch->arch rename an essential part of this patch?

>     struct cleanup *cleanup;
>
> -  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
> -
>     if (!arg)
>       arg = "";
>     arg = skip_spaces (arg);
> @@ -7884,13 +7880,30 @@ catch_load_or_unload (char *arg, int from_tty, int is_load,
>       }
>
>     c->is_load = is_load;
> -  init_catchpoint (&c->base, gdbarch, tempflag, NULL,
> +  init_catchpoint (&c->base, arch, is_temp, NULL,
>     &catch_solib_breakpoint_ops);

Same question here.

>
> +  c->base.enable_state = enabled ? bp_enabled : bp_disabled;
> +
>     discard_cleanups (cleanup);
>     install_breakpoint (0, &c->base, 1);
>   }
>
> +/* A helper function that does all the work for "catch load" and
> +   "catch unload".  */
> +
> +static void
> +catch_load_or_unload (char *arg, int from_tty, int is_load,
> +      struct cmd_list_element *command)
> +{
> +  int tempflag;
> +  const int enabled = 1;
> +
> +  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
> +
> +  add_solib_catchpoint (arg, is_load, tempflag, enabled);
> +}
> +
>   static void
>   catch_load_command_1 (char *arg, int from_tty,
>        struct cmd_list_element *command)
> diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
> index 8b1bcb7..11e432c 100644
> --- a/gdb/breakpoint.h
> +++ b/gdb/breakpoint.h
> @@ -1405,6 +1405,11 @@ extern void disable_breakpoints_in_shlibs (void);
>   /* This function returns TRUE if ep is a catchpoint.  */
>   extern int is_catchpoint (struct breakpoint *);
>
> +/* Shared helper function (MI and CLI) for creating and installing
> +   a shared object event catchpoint.  */
> +extern void add_solib_catchpoint (char *arg, int is_load, int is_temp,
> +                                  int enabled);
> +
>   /* Enable breakpoints and delete when hit.  Called with ARG == NULL
>      deletes all breakpoints.  */
>   extern void delete_command (char *arg, int from_tty);
> diff --git a/gdb/mi/mi-cmd-catch.c b/gdb/mi/mi-cmd-catch.c
> new file mode 100644
> index 0000000..c7b494e
> --- /dev/null
> +++ b/gdb/mi/mi-cmd-catch.c
> @@ -0,0 +1,126 @@
> +/* MI Command Set - catch commands.
> +   Copyright (C) 2012 Free Software Foundation, Inc.
> +
> +   Contributed by Intel Corporation.
> +
> +   This file is part of GDB.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see<http://www.gnu.org/licenses/>.  */
> +
> +#include "defs.h"
> +#include "arch-utils.h"
> +#include "breakpoint.h"
> +#include "gdb.h"
> +#include "libiberty.h"
> +#include "mi-cmds.h"
> +#include "mi-getopt.h"
> +#include "observer.h"
> +#include "ui-out.h"
> +
> +/* True if MI breakpoint observers have been registered.  */
> +
> +static int mi_catchpoint_observers_installed;
> +
> +/* Control whether breakpoint_notify may act.  */
> +
> +static int mi_can_catchpoint_notify;
> +
> +/* Output a single breakpoint, when allowed.  */

Please s/breakpoint/catchpoint/g in comments above. But actually, see below

> +
> +static void
> +catchpoint_notify (struct breakpoint *b)
> +{
> +  if (mi_can_catchpoint_notify)
> +    gdb_breakpoint_query (current_uiout, b->number, NULL);
> +}
> +
> +/* Common path for the -catch-load and -catch-unload.  */
> +
> +static void
> +mi_catch_load_unload (int load, char *argv[], int argc)
> +{
> +  struct solib_catchpoint *c;
> +  struct cleanup *back_to;
> +  char *actual_cmd = load ? "-catch-load" : "-catch-unload";
> +  int temp = 0;
> +  int enabled = 1;
> +  int oind = 0;
> +  char *oarg;
> +  enum opt
> +    {
> +      OPT_TEMP,
> +      OPT_DISABLED,
> +    };
> +  static const struct mi_opt opts[] =
> +    {
> +      { "t", OPT_TEMP, 0 },
> +      { "d", OPT_DISABLED, 0 },
> +      { 0, 0, 0 }
> +    };
> +
> +  for (;;)
> +    {
> +      int opt = mi_getopt (actual_cmd, argc, argv, opts,
> +                           &oind, &oarg);
> +
> +      if (opt < 0)
> +        break;
> +
> +      switch ((enum opt) opt)
> +        {
> +        case OPT_TEMP:
> +          temp = 1;
> +          break;
> +        case OPT_DISABLED:
> +          enabled = 0;
> +          break;
> +        }
> +    }
> +
> +  if (oind >= argc)
> +    error (_("-catch-load/unload: Missing <library name>"));
> +  if (oind < argc -1)
> +    error (_("-catch-load/unload: Garbage following the <library name>"));
> +
> +  if (! mi_catchpoint_observers_installed)
> +    {
> +      observer_attach_breakpoint_created (catchpoint_notify);
> +      mi_catchpoint_observers_installed = 1;
> +    }
> +
> +  back_to = make_cleanup_restore_integer (&mi_can_catchpoint_notify);
> +  mi_can_catchpoint_notify = 1;

To be honest, I am unsure that implicit copy-paste of this logic is a great idea, especially given that catchpoint_notify
and breakpoint_notify are identical. Maybe, a more appropriate solution would be to add this functionality to mi-cmd-break.c,
and extract the above snippet into a function called 'setup_new_breakpoint_reporting'?

Thanks,

--
Vladimir Prus
CodeSourcery / Mentor Graphics
http://www.mentor.com/embedded-software/
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v7 1/3] MI: add the -catch-load and -catch-unload commands

Mircea Gherzan-6
Hi,

Thanks for your review.

On 30.11.2012 13:56, Vladimir Prus wrote:
> On 29.11.2012 03:05, Mircea Gherzan wrote:
>> They are equivalent to "catch load" and "catch unload" from CLI.
[...]
>> +void
>> +add_solib_catchpoint (char *arg, int is_load, int is_temp, int enabled)
>>   {
>>     struct solib_catchpoint *c;
>> -  struct gdbarch *gdbarch = get_current_arch ();
>> -  int tempflag;
>> +  struct gdbarch *arch = get_current_arch ();
>
> Is gdbarch->arch rename an essential part of this patch?

No, not really. I took this out in v8 of the patch.

[...]

>> +
>> +  if (! mi_catchpoint_observers_installed)
>> +    {
>> +      observer_attach_breakpoint_created (catchpoint_notify);
>> +      mi_catchpoint_observers_installed = 1;
>> +    }
>> +
>> +  back_to = make_cleanup_restore_integer (&mi_can_catchpoint_notify);
>> +  mi_can_catchpoint_notify = 1;
>
> To be honest, I am unsure that implicit copy-paste of this logic is a
> great idea, especially given that catchpoint_notify
> and breakpoint_notify are identical. Maybe, a more appropriate solution
> would be to add this functionality to mi-cmd-break.c,
> and extract the above snippet into a function called
> 'setup_new_breakpoint_reporting'?

Thanks for the suggestion. The v8 is refactored in this way.

Regards,
Mircea


--

Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052