* gdb.ada/tasks: New testcase.
authorJoel Brobecker <brobecker@gnat.com>
Tue, 31 Mar 2009 16:48:49 +0000 (16:48 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 31 Mar 2009 16:48:49 +0000 (16:48 +0000)
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/tasks.exp [new file with mode: 0644]
gdb/testsuite/gdb.ada/tasks/foo.adb [new file with mode: 0644]

index ace10d75671389e127df01297c01d7a08718beae..cf1378f7c32312ef93c9641d88162c26cd3ad516 100644 (file)
@@ -1,3 +1,7 @@
+2009-03-31  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdb.ada/tasks: New testcase.
+
 2009-03-30  Stan Shebs  <stan@codesourcery.com>
 
        * gdb.trace/actions.exp: Update to match new info trace format.
diff --git a/gdb/testsuite/gdb.ada/tasks.exp b/gdb/testsuite/gdb.ada/tasks.exp
new file mode 100644 (file)
index 0000000..e5d9f92
--- /dev/null
@@ -0,0 +1,79 @@
+# Copyright 2009 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/>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+load_lib "ada.exp"
+
+set testdir "tasks"
+set testfile "${testdir}/foo"
+set srcfile ${srcdir}/${subdir}/${testfile}.adb
+set binfile ${objdir}/${subdir}/${testfile}
+
+file mkdir ${objdir}/${subdir}/${testdir}
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } {
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set bp_location [gdb_get_line_number "STOP_HERE" ${testdir}/foo.adb]
+runto "foo.adb:$bp_location"
+
+# Make sure that all tasks appear in the "info tasks" listing, and
+# that the active task is the environment task.
+gdb_test "info tasks" \
+         [join {"  ID       TID P-ID Pri State                  Name" \
+                "\\*  1 .* main_task" \
+                "   2 .* task_list\\(1\\)" \
+                "   3 .* task_list\\(2\\)" \
+                "   4 .* task_list\\(3\\)"} \
+               "\r\n"] \
+         "info tasks before inserting breakpoint"
+
+# Now, insert a breakpoint that should stop only if task 3 stops.
+gdb_test "break break_me task 3" "Breakpoint .* at .*"
+
+# Continue to that breakpoint.  Task 2 should hit it first, and GDB
+# is expected to ignore that hit and resume the execution.  Only then
+# task 3 will hit our breakpoint, and GDB is expected to stop at that
+# point.
+gdb_test "continue" \
+         ".*Breakpoint.*, foo.break_me \\(\\).*" \
+         "continue to breakpoint"
+
+# Check that it is indeed task 3 that hit the breakpoint by checking
+# which is the active task.
+gdb_test "info tasks" \
+         [join {"  ID       TID P-ID Pri State                  Name" \
+                "   1 .* main_task" \
+                "   2 .* task_list\\(1\\)" \
+                "\\*  3 .* task_list\\(2\\)" \
+                "   4 .* task_list\\(3\\)"} \
+               "\r\n"] \
+         "info tasks after hitting breakpoint"
+
+# 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_test "continue" \
+         ".*Program exited normally\..*" \
+         "continue until end of program"
+
diff --git a/gdb/testsuite/gdb.ada/tasks/foo.adb b/gdb/testsuite/gdb.ada/tasks/foo.adb
new file mode 100644 (file)
index 0000000..edf66be
--- /dev/null
@@ -0,0 +1,68 @@
+--  Copyright 2009 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/>.
+
+procedure Foo is
+
+   task type Caller is
+      entry Initialize;
+      entry Call_Break_Me;
+      entry Finalize;
+   end Caller;
+   type Caller_Ptr is access Caller;
+
+   procedure Break_Me is
+   begin
+      null;
+   end Break_Me;
+
+   task body Caller is
+   begin
+      accept Initialize do
+         null;
+      end Initialize;
+      accept Call_Break_Me do
+         Break_Me;
+      end Call_Break_Me;
+      accept Finalize do
+         null;
+      end Finalize;
+   end Caller;
+
+   Task_List : array (1 .. 3) of Caller_Ptr;
+
+begin
+
+   --  Start all our tasks, and call the "Initialize" entry to make
+   --  sure all of them have now been started.  We call that entry
+   --  immediately after having created the task in order to make sure
+   --  that we wait for that task to be created before we try to create
+   --  another one.  That way, we know that the order in our Task_List
+   --  corresponds to the order in the GNAT runtime.
+   for J in Task_List'Range loop
+      Task_List (J) := new Caller;
+      Task_List (J).Initialize;
+   end loop;
+
+   --  Next, call their Call_Break_Me entry of each task, using the same
+   --  order as the order used to create them.
+   for J in Task_List'Range loop  -- STOP_HERE
+      Task_List (J).Call_Break_Me;
+   end loop;
+
+   --  And finally, let all the tasks die...
+   for J in Task_List'Range loop
+      Task_List (J).Finalize;
+   end loop;
+end Foo;