diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3a730c83bd..cca1af9fc5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2017-12-14 Joel Brobecker + + * 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 * location.h (string_to_event_location): Add match_type diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index eac6c5be91..cd324b796a 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -783,18 +783,10 @@ read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info) = value_as_long (value_field (common_value, pspace_data->atcb_fieldno.base_cpu)); - /* And finally, compute the task ptid. Note that there are situations - where this cannot be determined: - - The task is no longer alive - the ptid is irrelevant; - - We are debugging a core file - the thread is not always - 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)) + /* And finally, compute the task ptid. Note that there is not point + in computing it if the task is no longer alive, in which case + it is good enough to set its ptid to the null_ptid. */ + if (ada_task_is_alive (task_info)) task_info->ptid = ptid_from_atcb_common (common_value); else 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') display_current_task_id (); else - { - /* 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 ()); - } + task_command_1 (taskno_str, from_tty, current_inferior ()); } /* Indicate that the given inferior's task list may have changed, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 5dc7fc2cd1..53c3780009 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-12-14 Joel Brobecker + + * gdb.ada/task_switch_in_core: New testcase. + 2017-12-13 Simon Marchi * gdb.python/py-breakpoint.c (foo_ns::multiply): New function. diff --git a/gdb/testsuite/gdb.ada/task_switch_in_core.exp b/gdb/testsuite/gdb.ada/task_switch_in_core.exp new file mode 100644 index 0000000000..92e749f763 --- /dev/null +++ b/gdb/testsuite/gdb.ada/task_switch_in_core.exp @@ -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 . + +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" diff --git a/gdb/testsuite/gdb.ada/task_switch_in_core/crash.adb b/gdb/testsuite/gdb.ada/task_switch_in_core/crash.adb new file mode 100644 index 0000000000..ae0170dae0 --- /dev/null +++ b/gdb/testsuite/gdb.ada/task_switch_in_core/crash.adb @@ -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 . + +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;