2003-02-28 08:08:51 +01:00
|
|
|
/* GDB Notifications to Observers.
|
2004-07-28 19:26:27 +02:00
|
|
|
|
2015-01-01 10:32:14 +01:00
|
|
|
Copyright (C) 2003-2015 Free Software Foundation, Inc.
|
2003-02-28 08:08:51 +01:00
|
|
|
|
|
|
|
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
|
2007-08-23 20:08:50 +02:00
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
2003-02-28 08:08:51 +01:00
|
|
|
(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
|
2007-08-23 20:08:50 +02:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
2003-02-28 08:08:51 +01:00
|
|
|
|
|
|
|
/* An observer is an entity who is interested in being notified when GDB
|
2011-01-10 21:38:51 +01:00
|
|
|
reaches certain states, or certain events occur in GDB. The entity being
|
|
|
|
observed is called the Subject. To receive notifications, the observer
|
|
|
|
attaches a callback to the subject. One subject can have several
|
2003-02-28 08:08:51 +01:00
|
|
|
observers.
|
|
|
|
|
|
|
|
This file implements an internal generic low-level event notification
|
|
|
|
mechanism based on the Observer paradigm described in the book "Design
|
|
|
|
Patterns". This generic event notification mechansim is then re-used
|
|
|
|
to implement the exported high-level notification management routines
|
|
|
|
for all possible notifications.
|
|
|
|
|
|
|
|
The current implementation of the generic observer provides support
|
2011-01-10 21:38:51 +01:00
|
|
|
for contextual data. This contextual data is given to the subject
|
|
|
|
when attaching the callback. In return, the subject will provide
|
2003-02-28 08:08:51 +01:00
|
|
|
this contextual data back to the observer as a parameter of the
|
|
|
|
callback.
|
|
|
|
|
|
|
|
FIXME: The current support for the contextual data is only partial,
|
|
|
|
as it lacks a mechanism that would deallocate this data when the
|
2011-01-10 21:38:51 +01:00
|
|
|
callback is detached. This is not a problem so far, as this contextual
|
|
|
|
data is only used internally to hold a function pointer. Later on,
|
2003-02-28 08:08:51 +01:00
|
|
|
if a certain observer needs to provide support for user-level
|
|
|
|
contextual data, then the generic notification mechanism will need
|
|
|
|
need to be enhanced to allow the observer to provide a routine to
|
|
|
|
deallocate the data when attaching the callback.
|
|
|
|
|
|
|
|
This file is currently maintained by hand, but the long term plan
|
|
|
|
if the number of different notifications starts growing is to create
|
|
|
|
a new script (observer.sh) that would generate this file, and the
|
|
|
|
associated documentation. */
|
|
|
|
|
|
|
|
#include "defs.h"
|
|
|
|
#include "observer.h"
|
2004-05-08 00:51:55 +02:00
|
|
|
#include "command.h"
|
|
|
|
#include "gdbcmd.h"
|
|
|
|
|
2012-08-02 11:36:40 +02:00
|
|
|
static unsigned int observer_debug;
|
2005-02-24 Andrew Cagney <cagney@gnu.org>
Add show_VARIABLE functions, update add_setshow call.
* varobj.c (_initialize_varobj, show_varobjdebug): Add and update.
* valprint.c (_initialize_valprint, show_print_max)
(show_stop_print_at_null, show_repeat_count_threshold)
(show_prettyprint_structs, show_unionprint)
(show_prettyprint_arrays, show_addressprint, show_input_radix)
(show_output_radix): Ditto.
* valops.c (_initialize_valops, show_overload_resolution): Ditto.
* utils.c (initialize_utils, show_chars_per_line)
(show_lines_per_page, show_demangle, show_pagination_enabled)
(show_sevenbit_strings, show_asm_demangle): Ditto
* tui/tui-win.c (_initialize_tui_win, show_tui_border_kind)
(show_tui_border_mode, show_tui_active_border_mode): Ditto.
* top.c (init_main, show_new_async_prompt)
(show_async_command_editing_p, show_write_history_p)
(show_history_size, show_history_filename, show_caution)
(show_annotation_level, init_main): Ditto.
* target.c (initialize_targets, show_targetdebug)
(show_trust_readonly): Ditto.
* symfile.c (_initialize_symfile, show_symbol_reloading)
(show_ext_args, show_download_write_size)
(show_debug_file_directory): Ditto.
* source.c (_initialize_source, show_lines_to_list): Ditto.
* solib.c (_initialize_solib, show_auto_solib_add)
(show_solib_search_path): Ditto.
* p-valprint.c (_initialize_pascal_valprint)
(show_pascal_static_field_print): Ditto.
* printcmd.c (_initialize_printcmd, show_max_symbolic_offset)
(show_print_symbol_filename): Add and update.
* parse.c (_initialize_parse, show_expressiondebug): Dito.
* observer.c (_initialize_observer, show_observer_debug): Dito.
* maint.c (_initialize_maint_cmds, show_watchdog)
(show_maintenance_profile_p): Dito.
* linux-nat.c (_initialize_linux_nat, show_debug_linux_nat): Dito.
* infrun.c (_initialize_infrun, show_debug_infrun)
(show_stop_on_solib_events, show_follow_fork_mode_string)
(show_scheduler_mode, show_step_stop_if_no_debug): Ditto.
* infcall.c (_initialize_infcall, show_coerce_float_to_double_p)
(show_unwind_on_signal_p): Ditto.
* gdbtypes.c (build_gdbtypes, show_opaque_type_resolution)
(_initialize_gdbtypes, show_overload_debug): Ditto.
* gdb-events.c, gdb-events.sh (_initialize_gdb_events)
(show_gdb_events_debug): Ditto.
* gdbarch.c, gdbarch.sh (show_gdbarch_debug)
(_initialize_gdbarch): Ditto.
* frame.c (_initialize_frame, show_backtrace_past_main)
(show_backtrace_past_entry, show_backtrace_limit)
(show_frame_debug): Ditto.
* exec.c (_initialize_exec, show_write_files): Ditto.
* dwarf2read.c (_initialize_dwarf2_read)
(show_dwarf2_max_cache_age): Ditto.
* demangle.c (_initialize_demangler)
(show_demangling_style_names): Ditto.
* dcache.c (_initialize_dcache, show_dcache_enabled_p): Ditto.
* cp-valprint.c (show_static_field_print)
(_initialize_cp_valprint, show_vtblprint, show_objectprint): Ditto.
* corefile.c (_initialize_core, show_gnutarget_string): Ditto.
* cli/cli-logging.c (_initialize_cli_logging)
(show_logging_overwrite, show_logging_redirect)
(show_logging_filename): Ditto.
* cli/cli-cmds.c (show_info_verbose, show_history_expansion_p)
(init_cli_cmds, show_baud_rate, show_remote_debug)
(show_remote_timeout, show_max_user_call_depth): Ditto.
* charset.c (show_host_charset_name, show_target_charset_name)
(initialize_charset): Ditto.
* breakpoint.c (show_can_use_hw_watchpoints)
(show_pending_break_support, _initialize_breakpoint): Ditto.
2005-02-24 14:51:36 +01:00
|
|
|
static void
|
|
|
|
show_observer_debug (struct ui_file *file, int from_tty,
|
|
|
|
struct cmd_list_element *c, const char *value)
|
|
|
|
{
|
|
|
|
fprintf_filtered (file, _("Observer debugging is %s.\n"), value);
|
|
|
|
}
|
2003-02-28 08:08:51 +01:00
|
|
|
|
|
|
|
/* The internal generic observer. */
|
|
|
|
|
|
|
|
typedef void (generic_observer_notification_ftype) (const void *data,
|
|
|
|
const void *args);
|
|
|
|
|
|
|
|
struct observer
|
|
|
|
{
|
|
|
|
generic_observer_notification_ftype *notify;
|
|
|
|
/* No memory management needed for the following field for now. */
|
|
|
|
void *data;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* A list of observers, maintained by the subject. A subject is
|
|
|
|
actually represented by its list of observers. */
|
|
|
|
|
|
|
|
struct observer_list
|
|
|
|
{
|
|
|
|
struct observer_list *next;
|
|
|
|
struct observer *observer;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Allocate a struct observer_list, intended to be used as a node
|
|
|
|
in the list of observers maintained by a subject. */
|
|
|
|
|
|
|
|
static struct observer_list *
|
|
|
|
xalloc_observer_list_node (void)
|
|
|
|
{
|
2013-12-28 23:31:23 +01:00
|
|
|
struct observer_list *node = XNEW (struct observer_list);
|
2010-05-16 02:46:46 +02:00
|
|
|
|
2013-12-28 23:31:23 +01:00
|
|
|
node->observer = XNEW (struct observer);
|
2003-02-28 08:08:51 +01:00
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The opposite of xalloc_observer_list_node, frees the memory for
|
|
|
|
the given node. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
xfree_observer_list_node (struct observer_list *node)
|
|
|
|
{
|
|
|
|
xfree (node->observer);
|
|
|
|
xfree (node);
|
|
|
|
}
|
|
|
|
|
2003-02-28 08:19:32 +01:00
|
|
|
/* Attach the callback NOTIFY to a SUBJECT. The DATA is also stored,
|
|
|
|
in order for the subject to provide it back to the observer during
|
|
|
|
a notification. */
|
2003-02-28 08:08:51 +01:00
|
|
|
|
|
|
|
static struct observer *
|
|
|
|
generic_observer_attach (struct observer_list **subject,
|
|
|
|
generic_observer_notification_ftype * notify,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
struct observer_list *observer_list = xalloc_observer_list_node ();
|
|
|
|
|
|
|
|
observer_list->next = *subject;
|
|
|
|
observer_list->observer->notify = notify;
|
|
|
|
observer_list->observer->data = data;
|
|
|
|
*subject = observer_list;
|
|
|
|
|
|
|
|
return observer_list->observer;
|
|
|
|
}
|
|
|
|
|
2003-02-28 08:19:32 +01:00
|
|
|
/* Remove the given OBSERVER from the SUBJECT. Once detached, OBSERVER
|
|
|
|
should no longer be used, as it is no longer valid. */
|
|
|
|
|
2003-02-28 08:08:51 +01:00
|
|
|
static void
|
|
|
|
generic_observer_detach (struct observer_list **subject,
|
|
|
|
const struct observer *observer)
|
|
|
|
{
|
|
|
|
struct observer_list *previous_node = NULL;
|
|
|
|
struct observer_list *current_node = *subject;
|
|
|
|
|
|
|
|
while (current_node != NULL)
|
|
|
|
{
|
|
|
|
if (current_node->observer == observer)
|
|
|
|
{
|
|
|
|
if (previous_node != NULL)
|
|
|
|
previous_node->next = current_node->next;
|
|
|
|
else
|
|
|
|
*subject = current_node->next;
|
|
|
|
xfree_observer_list_node (current_node);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
previous_node = current_node;
|
|
|
|
current_node = current_node->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We should never reach this point. However, this should not be
|
|
|
|
a very serious error, so simply report a warning to the user. */
|
2005-02-10 Andrew Cagney <cagney@gnu.org>
Mark up all error and warning messages.
* ada-lang.c, amd64-tdep.c, arch-utils.c, breakpoint.c: Update.
* bsd-kvm.c, bsd-uthread.c, coff-solib.h, coffread.c: Update.
* core-aout.c, core-regset.c, corefile.c, corelow.c: Update.
* cp-abi.c, cp-support.c, cp-valprint.c, cris-tdep.c: Update.
* dbxread.c, demangle.c, doublest.c, dsrec.c: Update.
* dve3900-rom.c, dwarf2expr.c, dwarf2loc.c: Update.
* dwarf2read.c, dwarfread.c, elfread.c, eval.c: Update.
* event-top.c, exec.c, expprint.c, f-lang.c: Update.
* f-typeprint.c, f-valprint.c, fbsd-nat.c, findvar.c: Update.
* frame.c, frv-linux-tdep.c, gcore.c, gdbtypes.c: Update.
* gnu-nat.c, gnu-v2-abi.c, gnu-v3-abi.c, go32-nat.c: Update.
* hpacc-abi.c, hppa-hpux-nat.c, hppa-hpux-tdep.c: Update.
* hppa-linux-nat.c, hppa-linux-tdep.c, hppa-tdep.c: Update.
* hpread.c, hpux-thread.c, i386-linux-nat.c: Update.
* i386-linux-tdep.c, i386-tdep.c, i386bsd-nat.c: Update.
* i386gnu-nat.c, i387-tdep.c, ia64-linux-nat.c: Update.
* ia64-tdep.c, inf-child.c, inf-ptrace.c, inf-ttrace.c: Update.
* infcall.c, infcmd.c, inflow.c, infptrace.c, infrun.c: Update.
* inftarg.c, interps.c, irix5-nat.c, jv-lang.c: Update.
* kod-cisco.c, kod.c, language.c, libunwind-frame.c: Update.
* linespec.c, linux-nat.c, linux-thread-db.c, m2-lang.c: Update.
* m32r-rom.c, m68hc11-tdep.c, m68k-tdep.c: Update.
* m68klinux-nat.c, macrocmd.c, macroexp.c, main.c: Update.
* maint.c, mdebugread.c, mem-break.c, memattr.c: Update.
* mips-linux-tdep.c, mips-tdep.c, mipsread.c, monitor.c: Update.
* nlmread.c, nto-procfs.c, objc-lang.c, objfiles.c: Update.
* observer.c, ocd.c, p-lang.c, p-typeprint.c: Update.
* p-valprint.c, pa64solib.c, parse.c, ppc-linux-tdep.c: Update.
* ppcnbsd-tdep.c, printcmd.c, procfs.c, remote-e7000.c: Update.
* remote-fileio.c, remote-m32r-sdi.c, remote-rdi.c: Update.
* remote-rdp.c, remote-sim.c, remote-st.c: Update.
* remote-utils.c, remote-utils.h, remote.c: Update.
* rom68k-rom.c, rs6000-nat.c, s390-tdep.c, scm-lang.c: Update.
* ser-e7kpc.c, ser-tcp.c, ser-unix.c, sh-tdep.c: Update.
* sh3-rom.c, shnbsd-tdep.c, sol-thread.c, solib-aix5.c: Update.
* solib-frv.c, solib-irix.c, solib-osf.c, solib-pa64.c: Update.
* solib-som.c, solib-sunos.c, solib-svr4.c, solib.c: Update.
* somread.c, somsolib.c, source.c, stabsread.c: Update.
* stack.c, std-regs.c, symfile-mem.c, symfile.c: Update.
* symmisc.c, symtab.c, target.c, thread.c, top.c: Update.
* tracepoint.c, trad-frame.c, typeprint.c, utils.c: Update.
* uw-thread.c, valarith.c, valops.c, valprint.c: Update.
* value.c, varobj.c, version.in, win32-nat.c, wince.c: Update.
* xcoffread.c, xcoffsolib.c, cli/cli-cmds.c: Update.
* cli/cli-decode.c, cli/cli-dump.c, cli/cli-logging.c: Update.
* cli/cli-script.c, cli/cli-setshow.c, mi/mi-cmd-break.c: Update.
* mi/mi-cmd-disas.c, mi/mi-cmd-env.c, mi/mi-cmd-file.c: Update.
* mi/mi-cmd-stack.c, mi/mi-cmd-var.c, mi/mi-getopt.c: Update.
* mi/mi-symbol-cmds.c, tui/tui-layout.c, tui/tui-stack.c: Update.
* tui/tui-win.c: Update.
2005-02-11 05:06:14 +01:00
|
|
|
warning (_("Failed to detach observer"));
|
2003-02-28 08:08:51 +01:00
|
|
|
}
|
|
|
|
|
2003-02-28 08:19:32 +01:00
|
|
|
/* Send a notification to all the observers of SUBJECT. ARGS is passed to
|
|
|
|
all observers as an argument to the notification callback. */
|
2003-02-28 08:08:51 +01:00
|
|
|
|
|
|
|
static void
|
|
|
|
generic_observer_notify (struct observer_list *subject, const void *args)
|
|
|
|
{
|
|
|
|
struct observer_list *current_node = subject;
|
|
|
|
|
|
|
|
while (current_node != NULL)
|
|
|
|
{
|
|
|
|
(*current_node->observer->notify) (current_node->observer->data, args);
|
|
|
|
current_node = current_node->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-18 19:05:51 +01:00
|
|
|
|
2003-12-12 17:14:26 +01:00
|
|
|
/* The following code is only used to unit-test the observers from our
|
|
|
|
testsuite. DO NOT USE IT within observer.c (or anywhere else for
|
|
|
|
that matter)! */
|
2003-03-18 19:05:51 +01:00
|
|
|
|
2003-12-12 17:14:26 +01:00
|
|
|
/* If we define these variables and functions as `static', the
|
|
|
|
compiler will optimize them out. */
|
2003-03-18 19:05:51 +01:00
|
|
|
|
2003-12-12 17:14:26 +01:00
|
|
|
int observer_test_first_observer = 0;
|
|
|
|
int observer_test_second_observer = 0;
|
|
|
|
int observer_test_third_observer = 0;
|
2003-03-18 19:05:51 +01:00
|
|
|
|
2012-03-01 22:12:05 +01:00
|
|
|
/* Provide prototypes to silence -Wmissing-prototypes. */
|
|
|
|
extern void observer_test_first_notification_function (int arg);
|
|
|
|
extern void observer_test_second_notification_function (int arg);
|
|
|
|
extern void observer_test_third_notification_function (int arg);
|
|
|
|
|
2003-12-12 17:14:26 +01:00
|
|
|
void
|
2009-02-17 20:52:27 +01:00
|
|
|
observer_test_first_notification_function (int arg)
|
2003-03-18 19:05:51 +01:00
|
|
|
{
|
|
|
|
observer_test_first_observer++;
|
|
|
|
}
|
|
|
|
|
2003-12-12 17:14:26 +01:00
|
|
|
void
|
2009-02-17 20:52:27 +01:00
|
|
|
observer_test_second_notification_function (int arg)
|
2003-03-18 19:05:51 +01:00
|
|
|
{
|
|
|
|
observer_test_second_observer++;
|
|
|
|
}
|
|
|
|
|
2003-12-12 17:14:26 +01:00
|
|
|
void
|
2009-02-17 20:52:27 +01:00
|
|
|
observer_test_third_notification_function (int arg)
|
2003-03-18 19:05:51 +01:00
|
|
|
{
|
|
|
|
observer_test_third_observer++;
|
|
|
|
}
|
|
|
|
|
2004-05-08 00:51:55 +02:00
|
|
|
extern initialize_file_ftype _initialize_observer; /* -Wmissing-prototypes */
|
|
|
|
|
|
|
|
void
|
|
|
|
_initialize_observer (void)
|
|
|
|
{
|
2012-08-02 11:36:40 +02:00
|
|
|
add_setshow_zuinteger_cmd ("observer", class_maintenance,
|
|
|
|
&observer_debug, _("\
|
2005-02-14 Andrew Cagney <cagney@gnu.org>
Mark up add_setshow functions, replace "PRINT:" comment prefix
with "FIXME: i18n:".
* aix-thread.c, alpha-tdep.c, arm-tdep.c, breakpoint.c: Update.
* cris-tdep.c, dwarf2read.c, frame.c, hppa-tdep.c: Update.
* infcall.c, m32r-rom.c, maint.c, mips-tdep.c: Update.
* nto-tdep.c, observer.c, remote-rdi.c, remote.c: Update.
* target.c, cli/cli-logging.c: Update.
2005-02-14 17:18:43 +01:00
|
|
|
Set observer debugging."), _("\
|
|
|
|
Show observer debugging."), _("\
|
|
|
|
When non-zero, observer debugging is enabled."),
|
2012-08-02 11:36:40 +02:00
|
|
|
NULL,
|
|
|
|
show_observer_debug,
|
|
|
|
&setdebuglist, &showdebuglist);
|
2004-05-08 00:51:55 +02:00
|
|
|
}
|
|
|
|
|
2004-04-15 16:29:21 +02:00
|
|
|
#include "observer.inc"
|