(Ada) Add support for task switching when debugging core files
The reasons for not supporting task switching when debugging core files appear to now mostly be OBE. In particular, on GNU/Linux, the thread layer is now able to retrieve the same thread info as in the live process. So, this patch is mostly about just removing the guard that limited the use of task switching to live processes. gdb/ChangeLog: * ada-tasks.c (read_atcb): Properly set task_info->ptid when !target_has_execution as well. (task_command): Remove error when !target_has_execution. gdb/testsuite/ChangeLog: * gdb.ada/task_switch_in_core: New testcase.
This commit is contained in:
parent
b3e7dd3c9d
commit
e05fa6f9df
|
@ -1,3 +1,9 @@
|
||||||
|
2017-12-14 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
|
* ada-tasks.c (read_atcb): Properly set task_info->ptid
|
||||||
|
when !target_has_execution as well.
|
||||||
|
(task_command): Remove error when !target_has_execution.
|
||||||
|
|
||||||
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
||||||
|
|
||||||
* location.h (string_to_event_location): Add match_type
|
* location.h (string_to_event_location): Add match_type
|
||||||
|
|
|
@ -783,18 +783,10 @@ read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info)
|
||||||
= value_as_long (value_field (common_value,
|
= value_as_long (value_field (common_value,
|
||||||
pspace_data->atcb_fieldno.base_cpu));
|
pspace_data->atcb_fieldno.base_cpu));
|
||||||
|
|
||||||
/* And finally, compute the task ptid. Note that there are situations
|
/* And finally, compute the task ptid. Note that there is not point
|
||||||
where this cannot be determined:
|
in computing it if the task is no longer alive, in which case
|
||||||
- The task is no longer alive - the ptid is irrelevant;
|
it is good enough to set its ptid to the null_ptid. */
|
||||||
- We are debugging a core file - the thread is not always
|
if (ada_task_is_alive (task_info))
|
||||||
completely preserved for us to link back a task to its
|
|
||||||
underlying thread. Since we do not support task switching
|
|
||||||
when debugging core files anyway, we don't need to compute
|
|
||||||
that task ptid.
|
|
||||||
In either case, we don't need that ptid, and it is just good enough
|
|
||||||
to set it to null_ptid. */
|
|
||||||
|
|
||||||
if (target_has_execution && ada_task_is_alive (task_info))
|
|
||||||
task_info->ptid = ptid_from_atcb_common (common_value);
|
task_info->ptid = ptid_from_atcb_common (common_value);
|
||||||
else
|
else
|
||||||
task_info->ptid = null_ptid;
|
task_info->ptid = null_ptid;
|
||||||
|
@ -1366,23 +1358,7 @@ task_command (const char *taskno_str, int from_tty)
|
||||||
if (taskno_str == NULL || taskno_str[0] == '\0')
|
if (taskno_str == NULL || taskno_str[0] == '\0')
|
||||||
display_current_task_id ();
|
display_current_task_id ();
|
||||||
else
|
else
|
||||||
{
|
task_command_1 (taskno_str, from_tty, current_inferior ());
|
||||||
/* Task switching in core files doesn't work, either because:
|
|
||||||
1. Thread support is not implemented with core files
|
|
||||||
2. Thread support is implemented, but the thread IDs created
|
|
||||||
after having read the core file are not the same as the ones
|
|
||||||
that were used during the program life, before the crash.
|
|
||||||
As a consequence, there is no longer a way for the debugger
|
|
||||||
to find the associated thead ID of any given Ada task.
|
|
||||||
So, instead of attempting a task switch without giving the user
|
|
||||||
any clue as to what might have happened, just error-out with
|
|
||||||
a message explaining that this feature is not supported. */
|
|
||||||
if (!target_has_execution)
|
|
||||||
error (_("\
|
|
||||||
Task switching not supported when debugging from core files\n\
|
|
||||||
(use thread support instead)"));
|
|
||||||
task_command_1 (taskno_str, from_tty, current_inferior ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indicate that the given inferior's task list may have changed,
|
/* Indicate that the given inferior's task list may have changed,
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2017-12-14 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
|
* gdb.ada/task_switch_in_core: New testcase.
|
||||||
|
|
||||||
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
||||||
|
|
||||||
* gdb.python/py-breakpoint.c (foo_ns::multiply): New function.
|
* gdb.python/py-breakpoint.c (foo_ns::multiply): New function.
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
# Copyright 2017 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 "ada.exp"
|
||||||
|
|
||||||
|
standard_ada_testfile crash
|
||||||
|
|
||||||
|
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
# Run the program to a certain point, and then use the gcore command
|
||||||
|
# to generate a core file. The only objective of this part of this
|
||||||
|
# testcase is to generate this core file, so we can then exercise
|
||||||
|
# task-switching when debugging from core files.
|
||||||
|
|
||||||
|
if { ![runto request_for_crash ]} then {
|
||||||
|
untested "couldn't run to Request_For_Crash"
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
set corefile [standard_output_file crash.gcore]
|
||||||
|
set core_supported [gdb_gcore_cmd "$corefile" "save a corefile"]
|
||||||
|
if {!$core_supported} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now taht the core file has been created, we can start the real
|
||||||
|
# part of this testcase, which is to debug using that core file.
|
||||||
|
# Restart GDB and load that core file.
|
||||||
|
|
||||||
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
set core_loaded [gdb_core_cmd "$corefile" "re-load generated corefile"]
|
||||||
|
if { $core_loaded == -1 } {
|
||||||
|
# No use proceeding from here.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# First, switch to task 1.
|
||||||
|
|
||||||
|
gdb_test "task 1" \
|
||||||
|
"crash\\.request_for_crash \\(\\) at .*crash\\.adb:$decimal.*"
|
||||||
|
|
||||||
|
|
||||||
|
gdb_test "info tasks" \
|
||||||
|
[multi_line "\\s+ID\\s+TID\\s+P-ID\\s+Pri\\s+State\\s+Name" \
|
||||||
|
"\\*\\s+1\\s+.*main_task" \
|
||||||
|
"\\s+2.*my_t"] \
|
||||||
|
"info tasks after switching to task 1"
|
||||||
|
|
||||||
|
# Switch to task 2. Unlike in the case where we tested the switch to
|
||||||
|
# task 1, don't check the location where the debugger says the program
|
||||||
|
# is, as this might depend on the runtime, and in particular it might
|
||||||
|
# depend on whether the runtime is built with debugging information
|
||||||
|
# or not. Just check that we get the "switching to task" message, and
|
||||||
|
# we will verify right after with an additional test that the current
|
||||||
|
# task is now task 2.
|
||||||
|
gdb_test "task 2" \
|
||||||
|
"\\\[Switching to task 2\\\].*"
|
||||||
|
|
||||||
|
gdb_test "info tasks" \
|
||||||
|
[multi_line "\\s+ID\\s+TID\\s+P-ID\\s+Pri\\s+State\\s+Name" \
|
||||||
|
"\\s+1\\s+.*main_task" \
|
||||||
|
"\\*\\s+2.*my_t"] \
|
||||||
|
"info tasks after switching to task 2"
|
|
@ -0,0 +1,53 @@
|
||||||
|
-- Copyright 2017 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/>.
|
||||||
|
|
||||||
|
with Ada.Text_IO; use Ada.Text_IO;
|
||||||
|
|
||||||
|
procedure Crash is
|
||||||
|
|
||||||
|
procedure Request_For_Crash is
|
||||||
|
begin
|
||||||
|
null; -- Just an anchor for the debugger...
|
||||||
|
end Request_For_Crash;
|
||||||
|
|
||||||
|
task type T is
|
||||||
|
entry Done;
|
||||||
|
end T;
|
||||||
|
|
||||||
|
task body T is
|
||||||
|
begin
|
||||||
|
accept Done do
|
||||||
|
null;
|
||||||
|
end Done;
|
||||||
|
Put_Line ("Task T: Rendez-vous completed.");
|
||||||
|
end T;
|
||||||
|
|
||||||
|
My_T : T;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- Give some time for the task to be created, and start its execution,
|
||||||
|
-- so that it reaches the accept statement.
|
||||||
|
delay 0.01;
|
||||||
|
|
||||||
|
Request_For_Crash;
|
||||||
|
|
||||||
|
delay 0.01;
|
||||||
|
Put_Line ("*** We didn't crash !?!");
|
||||||
|
|
||||||
|
-- Complete the rendez-vous with our task, so it can complete.
|
||||||
|
My_T.Done;
|
||||||
|
|
||||||
|
end Crash;
|
Loading…
Reference in New Issue