From c83d8d32c9b3379a39c434fcaa9f304b6e4432ca Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 21 Nov 2019 09:05:10 -0700 Subject: 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 * 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 * gdb.ada/tasks.exp: Add -ada-task-info regression test. * gdb.ada/tasks/foo.adb: Add another stopping location. Change-Id: If25eae6507eebb7537eb8adbcbaa1fc1eec88f5c --- gdb/ChangeLog | 6 ++++++ gdb/ada-tasks.c | 13 ++++++++----- gdb/gdbserver/ChangeLog | 5 +++++ gdb/testsuite/gdb.ada/tasks.exp | 8 +++++++- gdb/testsuite/gdb.ada/tasks/foo.adb | 3 +++ 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5dd8d42..cd26997 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2019-11-22 Tom Tromey + + * 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 * ada-exp.y: Update. diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index 110a710..67aa0c7 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -347,7 +347,7 @@ valid_task_id (int task_num) task state. */ 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); } @@ -1127,14 +1127,17 @@ print_ada_task_info (struct ui_out *uiout, /* Print the associated Thread ID. */ 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) uiout->field_signed ("thread-id", thread->global_num); else - /* This should never happen unless there is a bug somewhere, - but be resilient when that happens. */ - uiout->field_skip ("thread-id"); + { + /* This can happen if the thread is no longer alive. */ + uiout->field_skip ("thread-id"); + } } /* Print the ID of the parent task. */ diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index a5da6b5..0241438 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,8 @@ +2019-11-22 Tom Tromey + + * gdb.ada/tasks.exp: Add -ada-task-info regression test. + * gdb.ada/tasks/foo.adb: Add another stopping location. + 2019-11-20 Luis Machado * linux-aarch64-low.c (is_sve_tdesc): Check against target feature diff --git a/gdb/testsuite/gdb.ada/tasks.exp b/gdb/testsuite/gdb.ada/tasks.exp index 46a53fe..021e902 100644 --- a/gdb/testsuite/gdb.ada/tasks.exp +++ b/gdb/testsuite/gdb.ada/tasks.exp @@ -82,4 +82,10 @@ gdb_test "info tasks" \ # Now, resume the execution and make sure that GDB does not stop when # task 4 hits the breakpoint. Continuing thus results in our program # 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\"" ".*" diff --git a/gdb/testsuite/gdb.ada/tasks/foo.adb b/gdb/testsuite/gdb.ada/tasks/foo.adb index f95fed4..9fc43b0 100644 --- a/gdb/testsuite/gdb.ada/tasks/foo.adb +++ b/gdb/testsuite/gdb.ada/tasks/foo.adb @@ -65,4 +65,7 @@ begin for J in Task_List'Range loop Task_List (J).Finalize; end loop; + + null; -- STOP_HERE_2 + end Foo; -- cgit v1.1