Avoid crash in print_ada_task_info

In MI mode, print_ada_task_info can crash in find_thread_ptid when
trying to print an Ada task that is no longer alive.  This patch
avoids the problem by checking for this case.

Because this is Ada-specific, and because Joel approved it internally,
I am checking it in.

gdb/ChangeLog
2019-11-22  Tom Tromey  <tromey@adacore.com>

	* ada-tasks.c (ada_task_is_alive): Make parameter const.
	(print_ada_task_info): Don't try to fetch thread id if task is not
	alive.

gdb/gdbserver/ChangeLog
2019-11-22  Tom Tromey  <tromey@adacore.com>

	* gdb.ada/tasks.exp: Add -ada-task-info regression test.
	* gdb.ada/tasks/foo.adb: Add another stopping location.

Change-Id: If25eae6507eebb7537eb8adbcbaa1fc1eec88f5c
This commit is contained in:
Tom Tromey 2019-11-21 09:05:10 -07:00
parent 987012b89b
commit c83d8d32c9
5 changed files with 29 additions and 6 deletions

View file

@ -1,3 +1,9 @@
2019-11-22 Tom Tromey <tromey@adacore.com>
* ada-tasks.c (ada_task_is_alive): Make parameter const.
(print_ada_task_info): Don't try to fetch thread id if task is not
alive.
2019-11-22 Christian Biesinger <cbiesinger@google.com> 2019-11-22 Christian Biesinger <cbiesinger@google.com>
* ada-exp.y: Update. * ada-exp.y: Update.

View file

@ -347,7 +347,7 @@ valid_task_id (int task_num)
task state. */ task state. */
static int static int
ada_task_is_alive (struct ada_task_info *task_info) ada_task_is_alive (const struct ada_task_info *task_info)
{ {
return (task_info->state != Terminated); return (task_info->state != Terminated);
} }
@ -1127,15 +1127,18 @@ print_ada_task_info (struct ui_out *uiout,
/* Print the associated Thread ID. */ /* Print the associated Thread ID. */
if (uiout->is_mi_like_p ()) if (uiout->is_mi_like_p ())
{ {
thread_info *thread = find_thread_ptid (task_info->ptid); thread_info *thread = (ada_task_is_alive (task_info)
? find_thread_ptid (task_info->ptid)
: nullptr);
if (thread != NULL) if (thread != NULL)
uiout->field_signed ("thread-id", thread->global_num); uiout->field_signed ("thread-id", thread->global_num);
else else
/* This should never happen unless there is a bug somewhere, {
but be resilient when that happens. */ /* This can happen if the thread is no longer alive. */
uiout->field_skip ("thread-id"); uiout->field_skip ("thread-id");
} }
}
/* Print the ID of the parent task. */ /* Print the ID of the parent task. */
parent_id = get_task_number_from_id (task_info->parent, inf); parent_id = get_task_number_from_id (task_info->parent, inf);

View file

@ -1,3 +1,8 @@
2019-11-22 Tom Tromey <tromey@adacore.com>
* gdb.ada/tasks.exp: Add -ada-task-info regression test.
* gdb.ada/tasks/foo.adb: Add another stopping location.
2019-11-20 Luis Machado <luis.machado@linaro.org> 2019-11-20 Luis Machado <luis.machado@linaro.org>
* linux-aarch64-low.c (is_sve_tdesc): Check against target feature * linux-aarch64-low.c (is_sve_tdesc): Check against target feature

View file

@ -82,4 +82,10 @@ gdb_test "info tasks" \
# Now, resume the execution and make sure that GDB does not stop when # Now, resume the execution and make sure that GDB does not stop when
# task 4 hits the breakpoint. Continuing thus results in our program # task 4 hits the breakpoint. Continuing thus results in our program
# running to completion. # running to completion.
gdb_continue_to_end "" continue 1 set bp_location [gdb_get_line_number "STOP_HERE_2" ${testdir}/foo.adb]
gdb_breakpoint foo.adb:$bp_location
gdb_continue_to_breakpoint second ".*foo.adb:$bp_location.*null; -- STOP_HERE_2"
# A regression test for a crash caused by trying to find the thread
# for a terminated task.
gdb_test "interpreter-exec mi \"-ada-task-info\"" ".*"

View file

@ -65,4 +65,7 @@ begin
for J in Task_List'Range loop for J in Task_List'Range loop
Task_List (J).Finalize; Task_List (J).Finalize;
end loop; end loop;
null; -- STOP_HERE_2
end Foo; end Foo;