[PATCH 10/18] "multi-tasks-mode" support.

Joel Brobecker
2011-02-24T17:54:59Z

VxWorks systems do not provide a concept of a process, but some users
would really like to be able to debug all the tasks running in their
"program", and only those. The multi-tasks mode is an answer to that
request, based on the fact that Ada programs maintain a list of known
Ada tasks inside the runtime. The debugger can access it to compute
the current list of Ada tasks, and from there determine the list of
VxWorks threads running as part of the user's application.

Given the fact that this feature relies on a property of the GNAT runtime,
it only works for Ada applications.

Resuming/stopping the relevant threads is done by calls to specialized
routines in the GNAT runtime. This was necessary to avoid loads of
race conditions that we kept facing when doing this with WTX requests
to each and every affected thread. The runtime routines have nice
properties that allow us to avoid the problem entirely.

gdb/ChangeLog:

* remote-wtx-tasks.h, remote-wtx-tasks.c: New files.
---
gdb/remote-wtx-tasks.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++++
gdb/remote-wtx-tasks.h | 53 +++++++++++++
2 files changed, 254 insertions(+), 0 deletions(-)
create mode 100644 gdb/remote-wtx-tasks.c
create mode 100644 gdb/remote-wtx-tasks.h

diff --git a/gdb/remote-wtx-tasks.c b/gdb/remote-wtx-tasks.c
new file mode 100644
index 0000000..c876875
--- /dev/null
+++ b/gdb/remote-wtx-tasks.c
@@ -0,0 +1,201 @@
+/* Ada multi-task functionnalities for VxWorks targets.
+
+ Copyright 2005, 2010, 2011 Free Software Foundation, Inc.
+
+ 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/>. */
+
+/* Some symbol names embedded in the inferior when it uses tasks. */
+
+#include "defs.h"
+#include "remote-wtxapi.h"
+#include "remote-wtx-bp.h"
+#include "remote-wtx-tasks.h"
+#include "gdbcmd.h"
+#include "target.h"
+
+#define ADA_STOP_ALL_TASKS ("system__tasking__debug__stop_all_tasks")
+#define ADA_STOP_ALL_TASKS_HANDLER ("system__tasking__debug__stop_all_tasks_handler")
+#define ADA_CONTINUE_ALL_TASKS ("system__tasking__debug__continue_all_tasks")
+
+/* Breakpoint scope/action operations for the Ada multitask mode :
+ Ada application scope/Ada application action. */
+
+static int multi_task_mode = 0;
+
+/* The user must not be allowed to change the value of the multitask
+ mode while debugging. Unfortunately, the set/show mechanism does
+ not allow us to add this type of guard directly. So what we do is
+ we let the "set multi-tasks-mode" command update the intermediate
+ variable below, and then let a hook called at each update propagate
+ the new value to MULTI_TASK_MODE if allowed, or report an error
+ if not. */
+static int multi_task_mode_setshow_var = 0;
+
+/* Some variables used to cache the address of functions provided by the
+ inferior to suspend/resume all ada tasks. */
+
+static CORE_ADDR continue_all_tasks_fun_addr = 0;
+static CORE_ADDR stop_all_tasks_handler_fun_addr = 0;
+static CORE_ADDR stop_all_tasks_fun_addr = 0;
+
+/* Return non-zero if the user has selected the multi-tasks mode. */
+
+int
+multi_task_mode_is_on (void)
+{
+ return multi_task_mode;
+}
+
+/* Initialize the breakpoint datas for the multi-tasks mode. */
+
+void
+open_multi_task_mode (void)
+{
+ set_break_command_action (action_call);
+ set_break_command_call_rtn (stop_all_tasks_handler_fun_addr);
+}
+
+/* Initialize the breakpoint datas for the single-tasks mode. */
+
+void
+close_multi_task_mode (void)
+{
+ set_break_command_action (action_task);
+ set_break_command_call_rtn (0);
+}
+
+/* Hook called after the "set multi-tasks-mode" command has been
+ executed. This function verifies that the debugger is not already
+ debugging a process, or else cancels the user request with an
+ error message. Otherwise, the request is processed by setting
+ MULTI_TASK_MODE to the new value. */
+
+static void
+set_multi_tasks_mode_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ /* If we are already debugging a process, reset MULTI_TASK_MODE_SETSHOW_VAR
+ and report an error. */
+ if (target_has_execution)
+ {
+ multi_task_mode_setshow_var = multi_task_mode;
+ error (_("\
+The multi-tasks mode cannot be changed while debugging a process"));
+ }
+
+ multi_task_mode = multi_task_mode_setshow_var;
+}
+
+void
+_initialize_remote_wtx_tasks (void)
+{
+ add_setshow_boolean_cmd ("multi-tasks-mode", no_class,
+ &multi_task_mode_setshow_var,"\
+Set whether gdb is debugging the whole Ada kernel application on VxWorks.", "\
+Show whether gdb is debugging the whole Ada kernel application on VxWorks.", "\
+If set, on VxWorks, gdb debugs the whole Ada kernel application.",
+ set_multi_tasks_mode_cmd, NULL,
+ &setlist, &showlist);
+}
+
+/* Set the multi-tasks mode user setting to off (zero). */
+
+void
+turn_multi_task_mode_off (void)
+{
+ multi_task_mode = 0;
+ multi_task_mode_setshow_var = 0;
+}
+
+/* Close the multi-tasking support. */
+
+void
+stop_multi_task_mode (void)
+{
+ stop_all_tasks_fun_addr = 0;
+ continue_all_tasks_fun_addr = 0;
+ stop_all_tasks_handler_fun_addr = 0;
+
+ set_break_command_action (action_task);
+ set_break_command_call_rtn (0);
+}
+
+/* Set up the multi-tasks mode.
+
+ Automatically deactivate the multi-tasks mode if the inferior
+ is found to not use Ada tasks. */
+
+void
+start_multi_task_mode (void)
+{
+ set_break_command_action (action_call);
+
+ remote_wtxapi_get_symbol_address (ADA_STOP_ALL_TASKS,
+ &stop_all_tasks_fun_addr);
+ remote_wtxapi_get_symbol_address (ADA_CONTINUE_ALL_TASKS,
+ &continue_all_tasks_fun_addr);
+
+ if (stop_all_tasks_fun_addr == 0 || continue_all_tasks_fun_addr == 0)
+ {
+ warning (_("Your application does not use Ada tasking.\n\
+multi-tasks-mode turned off."));
+ turn_multi_task_mode_off ();
+ stop_multi_task_mode ();
+ return;
+ }
+
+ /* Search for ADA_STOP_ALL_TASKS_HANDLER and install it if we can
+ find it. */
+ remote_wtxapi_get_symbol_address (ADA_STOP_ALL_TASKS_HANDLER,
+ &stop_all_tasks_handler_fun_addr);
+ if (stop_all_tasks_handler_fun_addr != 0)
+ set_break_command_call_rtn (stop_all_tasks_handler_fun_addr);
+}
+
+/* Resume all Ada tasks in our inferior. */
+
+int
+continue_all_ada_tasks ()
+{
+ long *ignored_retval;
+
+ if (continue_all_tasks_fun_addr != 0)
+ return wtxapi_direct_call (continue_all_tasks_fun_addr, &ignored_retval,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ return 0;
+}
+
+/* Stop all Ada tasks in our inferior. After this operation, the Ada tasks
+ can be either suspended, and stopped, depending of the vxWorks version;
+ this information is returned in STATUS. */
+
+int
+stop_all_ada_tasks (enum wtx_task_status *status)
+{
+ long *ignored_retval;
+
+ if (stop_all_tasks_fun_addr != 0)
+ {
+ *status = WTX_TASK_STATUS_STOPPED;
+ return wtxapi_direct_call (stop_all_tasks_fun_addr, &ignored_retval,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+
+ *status = WTX_TASK_STATUS_RUNNING;
+ return 0;
+}
+
diff --git a/gdb/remote-wtx-tasks.h b/gdb/remote-wtx-tasks.h
new file mode 100644
index 0000000..116a5f6
--- /dev/null
+++ b/gdb/remote-wtx-tasks.h
@@ -0,0 +1,53 @@
+/* Ada multi-task functionnalities for VxWorks targets.
+
+ Copyright 2005, 2010, 2011 Free Software Foundation, Inc.
+
+ 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/>. */
+
+/* FIXME: brobecke/2007-10-19: We're introducing a new API which should
+ be simpler to use.
+
+ In order to avoid colliding with the deprecated interface, we will
+ temporarily break the naming scheme and not prepend our function
+ names with "wtx_tasks_" for now. The plan is to rename all the
+ deprecated routines using the "deprecated_" prefix, followed by
+ renaming these new functions. To be done later. */
+
+/* Task status; used to know which routine to use when resuming the
+ inferior. Note that STOPPED and SUSPENDED are actually the same
+ status on VxWorks 5. */
+
+enum wtx_task_status
+ {
+ WTX_TASK_STATUS_CREATED,
+ WTX_TASK_STATUS_RUNNING,
+ WTX_TASK_STATUS_STOPPED,
+ WTX_TASK_STATUS_SUSPENDED,
+ WTX_TASK_STATUS_UNKNOWN
+ };
+
+int multi_task_mode_is_on (void);
+
+void turn_multi_task_mode_off (void);
+
+void start_multi_task_mode (void);
+
+void stop_multi_task_mode (void);
+
+int continue_all_ada_tasks (void);
+
+int stop_all_ada_tasks (enum wtx_task_status *status);
+
--
1.7.0.4