gdb/testsuite/
* gdb.trace/unavailable.cc, gdb.trace/unavailable.exp: New files.
This commit is contained in:
parent
a3d34bf49a
commit
06d72e16c4
3 changed files with 450 additions and 0 deletions
|
@ -1,3 +1,7 @@
|
|||
2011-02-14 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* gdb.trace/unavailable.cc, gdb.trace/unavailable.exp: New files.
|
||||
|
||||
2011-02-13 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Fix const/volatile qualifiers of C++ types, PR c++/12328.
|
||||
|
|
204
gdb/testsuite/gdb.trace/unavailable.cc
Normal file
204
gdb/testsuite/gdb.trace/unavailable.cc
Normal file
|
@ -0,0 +1,204 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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/>. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Test program partial trace data visualization. */
|
||||
|
||||
/* Typedefs. */
|
||||
|
||||
typedef struct TEST_STRUCT {
|
||||
char memberc;
|
||||
int memberi;
|
||||
float memberf;
|
||||
double memberd;
|
||||
} test_struct;
|
||||
|
||||
typedef int test_array [4];
|
||||
|
||||
/* Global variables to be collected. */
|
||||
|
||||
char globalc;
|
||||
int globali;
|
||||
float globalf;
|
||||
double globald;
|
||||
test_struct globalstruct;
|
||||
test_struct *globalp;
|
||||
int globalarr[16];
|
||||
|
||||
/* Strings. */
|
||||
|
||||
const char g_const_string[] = "hello world";
|
||||
char g_string_unavail[sizeof (g_const_string)];
|
||||
char g_string_partial[sizeof (g_const_string)];
|
||||
const char *g_string_p;
|
||||
|
||||
/* Used to check that <unavailable> is not the same as 0 in array
|
||||
element repetitions. */
|
||||
|
||||
struct tuple
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
struct tuple tarray[8];
|
||||
|
||||
/* Random tests. */
|
||||
|
||||
struct StructA
|
||||
{
|
||||
int a, b;
|
||||
int array[10000];
|
||||
void *ptr;
|
||||
int bitfield:1;
|
||||
};
|
||||
|
||||
struct StructB
|
||||
{
|
||||
int d, ef;
|
||||
StructA struct_a;
|
||||
int s:1;
|
||||
static StructA static_struct_a;
|
||||
const char *string;
|
||||
};
|
||||
|
||||
/* References. */
|
||||
|
||||
int g_int;
|
||||
int &g_ref = g_int;
|
||||
|
||||
struct StructRef
|
||||
{
|
||||
StructRef (unsigned int val) : ref(d) {}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
d = 0;
|
||||
}
|
||||
|
||||
unsigned int d;
|
||||
unsigned int &ref;
|
||||
};
|
||||
|
||||
struct StructB struct_b;
|
||||
struct StructA StructB::static_struct_a;
|
||||
|
||||
StructRef g_structref(0x12345678);
|
||||
StructRef *g_structref_p = &g_structref;
|
||||
|
||||
|
||||
/* Test functions. */
|
||||
|
||||
static void
|
||||
begin () /* called before anything else */
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
end () /* called after everything else */
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
globals_test_func ()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
i += globalc + globali + globalf + globald;
|
||||
i += globalstruct.memberc + globalstruct.memberi;
|
||||
i += globalstruct.memberf + globalstruct.memberd;
|
||||
i += globalarr[1];
|
||||
|
||||
return i; /* set globals_test_func tracepoint here */
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv, char **envp)
|
||||
{
|
||||
int i = 0;
|
||||
test_struct mystruct;
|
||||
int myarray[4];
|
||||
|
||||
begin ();
|
||||
/* Assign collectable values to global variables. */
|
||||
globalc = 71;
|
||||
globali = 72;
|
||||
globalf = 73.3;
|
||||
globald = 74.4;
|
||||
globalstruct.memberc = 81;
|
||||
globalstruct.memberi = 82;
|
||||
globalstruct.memberf = 83.3;
|
||||
globalstruct.memberd = 84.4;
|
||||
globalp = &globalstruct;
|
||||
|
||||
for (i = 0; i < 15; i++)
|
||||
globalarr[i] = i;
|
||||
|
||||
mystruct.memberc = 101;
|
||||
mystruct.memberi = 102;
|
||||
mystruct.memberf = 103.3;
|
||||
mystruct.memberd = 104.4;
|
||||
myarray[0] = 111;
|
||||
myarray[1] = 112;
|
||||
myarray[2] = 113;
|
||||
myarray[3] = 114;
|
||||
|
||||
g_int = 123;
|
||||
memset (&struct_b, 0xaa, sizeof struct_b);
|
||||
memset (&struct_b.static_struct_a, 0xaa, sizeof struct_b.static_struct_a);
|
||||
struct_b.string = g_const_string;
|
||||
memcpy (g_string_unavail, g_const_string, sizeof (g_const_string));
|
||||
memcpy (g_string_partial, g_const_string, sizeof (g_const_string));
|
||||
g_string_p = g_const_string;
|
||||
|
||||
/* Call test functions, so they can be traced and data collected. */
|
||||
i = 0;
|
||||
i += globals_test_func ();
|
||||
|
||||
/* Set 'em back to zero, so that the collected values will be
|
||||
distinctly different from the "realtime" (end of test) values. */
|
||||
|
||||
globalc = 0;
|
||||
globali = 0;
|
||||
globalf = 0;
|
||||
globald = 0;
|
||||
globalstruct.memberc = 0;
|
||||
globalstruct.memberi = 0;
|
||||
globalstruct.memberf = 0;
|
||||
globalstruct.memberd = 0;
|
||||
globalp = 0;
|
||||
for (i = 0; i < 15; i++)
|
||||
globalarr[i] = 0;
|
||||
|
||||
memset (&struct_b, 0, sizeof struct_b);
|
||||
memset (&struct_b.static_struct_a, 0, sizeof struct_b.static_struct_a);
|
||||
struct_b.string = NULL;
|
||||
memset (g_string_unavail, 0, sizeof (g_string_unavail));
|
||||
memset (g_string_partial, 0, sizeof (g_string_partial));
|
||||
g_string_p = NULL;
|
||||
|
||||
g_int = 0;
|
||||
|
||||
g_structref.clear ();
|
||||
g_structref_p = NULL;
|
||||
|
||||
end ();
|
||||
return 0;
|
||||
}
|
242
gdb/testsuite/gdb.trace/unavailable.exp
Normal file
242
gdb/testsuite/gdb.trace/unavailable.exp
Normal file
|
@ -0,0 +1,242 @@
|
|||
# Copyright 1998, 2005, 2007, 2008, 2009, 2010, 2011
|
||||
# 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 "trace-support.exp"
|
||||
|
||||
set testfile "unavailable"
|
||||
set srcfile ${testfile}.cc
|
||||
set executable $testfile
|
||||
set binfile $objdir/$subdir/$executable
|
||||
|
||||
if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
|
||||
executable {debug nowarnings c++}] != "" } {
|
||||
untested unavailable.exp
|
||||
return -1
|
||||
}
|
||||
|
||||
set ws "\[\r\n\t \]+"
|
||||
set cr "\[\r\n\]+"
|
||||
|
||||
#
|
||||
# Utility procs
|
||||
#
|
||||
|
||||
proc prepare_for_trace_test {} {
|
||||
global executable
|
||||
|
||||
clean_restart $executable
|
||||
|
||||
runto_main
|
||||
|
||||
gdb_test "break begin" ".*" ""
|
||||
gdb_test "break end" ".*" ""
|
||||
}
|
||||
|
||||
proc run_trace_experiment { test_func } {
|
||||
global gdb_prompt
|
||||
|
||||
gdb_test "continue" \
|
||||
".*Breakpoint \[0-9\]+, begin .*" \
|
||||
"advance to begin"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test "continue" \
|
||||
"Continuing.*Breakpoint \[0-9\]+, end.*" \
|
||||
"run trace experiment"
|
||||
gdb_test "tstop" \
|
||||
"\[\r\n\]+" \
|
||||
"stop trace experiment"
|
||||
gdb_test "tfind start" \
|
||||
"#0 $test_func .*" \
|
||||
"tfind test frame"
|
||||
}
|
||||
|
||||
#
|
||||
# Test procs
|
||||
#
|
||||
|
||||
proc gdb_collect_globals_test { } {
|
||||
global ws
|
||||
global cr
|
||||
global gdb_prompt
|
||||
global hex
|
||||
global pf_prefix
|
||||
|
||||
set old_pf_prefix $pf_prefix
|
||||
set pf_prefix "$pf_prefix collect globals:"
|
||||
|
||||
prepare_for_trace_test
|
||||
|
||||
set testline [gdb_get_line_number "set globals_test_func tracepoint here"]
|
||||
|
||||
gdb_test "trace $testline" \
|
||||
"Tracepoint \[0-9\]+ at .*" \
|
||||
"set tracepoint"
|
||||
|
||||
gdb_trace_setactions "define actions" \
|
||||
"" \
|
||||
"collect struct_b.struct_a.array\[2\]" "^$" \
|
||||
"collect struct_b.struct_a.array\[100\]" "^$" \
|
||||
\
|
||||
"collect tarray\[0\].a" "^$" \
|
||||
"collect tarray\[1\].a" "^$" \
|
||||
"collect tarray\[3\].a" "^$" \
|
||||
"collect tarray\[3\].b" "^$" \
|
||||
"collect tarray\[4\].b" "^$" \
|
||||
"collect tarray\[5\].b" "^$" \
|
||||
\
|
||||
"collect g_string_p" "^$" \
|
||||
"collect g_string_partial\[1\]" "^$" \
|
||||
"collect g_string_partial\[2\]" "^$" \
|
||||
\
|
||||
"collect g_structref_p" "^$" \
|
||||
|
||||
# Begin the test.
|
||||
run_trace_experiment globals_test_func
|
||||
|
||||
gdb_test "print globalc" " = <unavailable>"
|
||||
gdb_test "print globali" " = <unavailable>"
|
||||
gdb_test "print globalf" " = <unavailable>"
|
||||
gdb_test "print globald" " = <unavailable>"
|
||||
|
||||
gdb_test "print globalstruct.memberc" " = <unavailable>"
|
||||
gdb_test "print globalstruct.memberi" " = <unavailable>"
|
||||
gdb_test "print globalstruct.memberf" " = <unavailable>"
|
||||
gdb_test "print globalstruct.memberd" " = <unavailable>"
|
||||
|
||||
gdb_test "print globalstruct" \
|
||||
" = {memberc = <unavailable>, memberi = <unavailable>, memberf = <unavailable>, memberd = <unavailable>}"
|
||||
|
||||
gdb_test "print globalp == &globalstruct" \
|
||||
"value is not available" \
|
||||
"can't compare using non collected global pointer"
|
||||
|
||||
gdb_test "print globalarr\[1\]" " = <unavailable>"
|
||||
gdb_test "print globalarr\[2\]" " = <unavailable>"
|
||||
gdb_test "print globalarr\[3\]" " = <unavailable>"
|
||||
|
||||
gdb_test "print struct_b" \
|
||||
" = {d = <unavailable>, ef = <unavailable>, struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, -1431655766, <unavailable> <repeats 97 times>, -1431655766, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}, s = <unavailable>, static static_struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}, string = <unavailable>}"
|
||||
|
||||
gdb_test "print /x struct_b" \
|
||||
" = {d = <unavailable>, ef = <unavailable>, struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}, s = <unavailable>, static static_struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}, string = <unavailable>}"
|
||||
|
||||
gdb_test "print /x struct_b.struct_a" \
|
||||
" = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}"
|
||||
|
||||
gdb_test "print /x struct_b.struct_a.array" \
|
||||
" = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}"
|
||||
|
||||
gdb_test "print /x struct_b.struct_a.array\[0\]" " = <unavailable>"
|
||||
|
||||
gdb_test "print /x struct_b.struct_a.array\[2\]" " = 0xaaaaaaaa"
|
||||
|
||||
# Check <unavailable> isn't confused with 0 in array element repetitions
|
||||
|
||||
gdb_test_no_output "set print repeat 1"
|
||||
|
||||
gdb_test "print /x tarray" \
|
||||
" = \{\{a = 0x0, b = <unavailable>\} <repeats 2 times>, \{a = <unavailable>, b = <unavailable>\}, \{a = 0x0, b = 0x0\}, \{a = <unavailable>, b = 0x0\} <repeats 2 times>, \{a = <unavailable>, b = <unavailable>\} <repeats 2 times>\}" \
|
||||
"<unavailable> is not the same as 0 in array element repetitions"
|
||||
|
||||
gdb_test_no_output "set print repeat 10"
|
||||
|
||||
# Static fields
|
||||
|
||||
gdb_test "print struct_b.static_struct_a" \
|
||||
" = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}"
|
||||
|
||||
# Bitfields
|
||||
|
||||
gdb_test "print struct_b.struct_a.bitfield" " = <unavailable>"
|
||||
|
||||
# References
|
||||
|
||||
gdb_test "print g_int" " = <unavailable>"
|
||||
|
||||
gdb_test "print g_ref" \
|
||||
"\\(int &\\) @$hex: <unavailable>" \
|
||||
"global reference shows address but not value"
|
||||
|
||||
gdb_test "print *&g_ref" \
|
||||
"\\$\[0-9\]+ = <unavailable>$cr" \
|
||||
"referenced integer was not collected (taking address of reference)"
|
||||
|
||||
gdb_test "print *g_structref_p" \
|
||||
" = {d = <unavailable>, ref = <unavailable>}"
|
||||
|
||||
# Strings
|
||||
|
||||
# Const string is always available, even when not collected.
|
||||
gdb_test "print g_const_string" \
|
||||
" = \"hello world\"$cr" \
|
||||
"non collected const string is still printable"
|
||||
|
||||
gdb_test "print g_string_p" \
|
||||
" = $hex \"hello world\"" \
|
||||
"printing constant string through collected pointer"
|
||||
|
||||
gdb_test "print g_string_unavail" \
|
||||
" = \{<unavailable> <repeats 12 times>\}" \
|
||||
"printing non collected string"
|
||||
|
||||
# Incomplete strings print as an array.
|
||||
gdb_test "print g_string_partial" \
|
||||
"\\$\[0-9\]+ = \{<unavailable>, 101 'e', 108 'l', <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>\}" \
|
||||
"printing partially collected string"
|
||||
|
||||
# It is important for this test that the last examined value is
|
||||
# <unavailable>, to exercise the case of the $__ convenience
|
||||
# variable being set to <unavailable> without error.
|
||||
set msg "examining partially collected object"
|
||||
gdb_test_multiple "x /10x &struct_b" "$msg" {
|
||||
-re "$hex <struct_b>:${ws}<unavailable>${ws}<unavailable>${ws}<unavailable>${ws}<unavailable>$cr$hex <struct_b\\+16>:${ws}<unavailable>${ws}<unavailable>${ws}0xaaaaaaaa${ws}<unavailable>$cr$hex <struct_b\\+32>:${ws}<unavailable>${ws}<unavailable>$cr$gdb_prompt $" {
|
||||
pass "$msg"
|
||||
}
|
||||
-re "value is not available" {
|
||||
fail "$msg"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "p \$__" " = <unavailable>" "last examined value was <unavailable>"
|
||||
|
||||
gdb_test "tfind none" \
|
||||
"#0 end .*" \
|
||||
"cease trace debugging"
|
||||
|
||||
set pf_prefix $old_pf_prefix
|
||||
}
|
||||
|
||||
proc gdb_trace_collection_test {} {
|
||||
gdb_collect_globals_test
|
||||
}
|
||||
|
||||
clean_restart $executable
|
||||
runto_main
|
||||
|
||||
# We generously give ourselves one "pass" if we successfully
|
||||
# detect that this test cannot be run on this target!
|
||||
if { ![gdb_target_supports_trace] } then {
|
||||
pass "Current target does not support trace"
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Body of test encased in a proc so we can return prematurely.
|
||||
gdb_trace_collection_test
|
||||
|
||||
# Finished!
|
||||
gdb_test "tfind none" ".*" ""
|
Loading…
Reference in a new issue