gdb/doc/ChangeLog:

2012-04-27  Sergio Durigan Junior  <sergiodj@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (Static Probe Points): New entry, explaining SystemTap
	and generic static probe support on GDB.

gdb/testsuite/ChangeLog:
2012-04-27  Sergio Durigan Junior  <sergiodj@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* gdb.base/default.exp: Add `$_probe_arg*' convenience
	variables.
	* gdb.base/stap-probe.c: New file.
	* gdb.base/stap-probe.exp: New file.
	* gdb.trace/stap-trace.c: New file.
	* gdb.trace/stap-trace.exp: New file.
	* gdb.cp/nextoverthrow.exp: Add check for SystemTap probe in
	libgcc's unwinder.
This commit is contained in:
Sergio Durigan Junior
2012-04-27 20:52:06 +00:00
parent 28106bc2fe
commit 62e5f89c34
9 changed files with 623 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2012-04-27 Sergio Durigan Junior <sergiodj@redhat.com>
Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Static Probe Points): New entry, explaining SystemTap
and generic static probe support on GDB.
2012-04-25 Doug Evans <dje@google.com> 2012-04-25 Doug Evans <dje@google.com>
* gdb.texinfo (Go): Fix thinko. * gdb.texinfo (Go): Fix thinko.

View File

@ -3342,6 +3342,7 @@ all breakpoints in that range are operated on.
* Conditions:: Break conditions * Conditions:: Break conditions
* Break Commands:: Breakpoint command lists * Break Commands:: Breakpoint command lists
* Save Breakpoints:: How to save breakpoints in a file * Save Breakpoints:: How to save breakpoints in a file
* Static Probe Points:: Listing static probe points
* Error in Breakpoints:: ``Cannot insert breakpoints'' * Error in Breakpoints:: ``Cannot insert breakpoints''
* Breakpoint-related Warnings:: ``Breakpoint address adjusted...'' * Breakpoint-related Warnings:: ``Breakpoint address adjusted...''
@end menu @end menu
@ -4652,6 +4653,69 @@ and remove the breakpoint definitions you're not interested in, or
that can no longer be recreated. that can no longer be recreated.
@end table @end table
@node Static Probe Points
@subsection Static Probe Points
@cindex static probe point, SystemTap
@value{GDBN} supports @dfn{SDT} probes in the code. @acronym{SDT} stands
for Statically Defined Tracing, and the probes are designed to have a tiny
runtime code and data footprint, and no dynamic relocations. They are
usable from assembly, C and C@t{++} languages. See
@uref{http://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation}
for a good reference on how the @acronym{SDT} probes are implemented.
Currently, @code{SystemTap} (@uref{http://sourceware.org/systemtap/})
@acronym{SDT} probes are supported on ELF-compatible systems. See
@uref{http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps}
for more information on how to add @code{SystemTap} @acronym{SDT} probes
in your applications.
@cindex semaphores on static probe points
Some probes have an associated semaphore variable; for instance, this
happens automatically if you defined your probe using a DTrace-style
@file{.d} file. If your probe has a semaphore, @value{GDBN} will
automatically enable it when you specify a breakpoint using the
@samp{-probe-stap} notation. But, if you put a breakpoint at a probe's
location by some other method (e.g., @code{break file:line}), then
@value{GDBN} will not automatically set the semaphore.
You can examine the available static static probes using @code{info
probes}, with optional arguments:
@table @code
@kindex info probes
@item info probes stap @r{[}@var{provider} @r{[}@var{name} @r{[}@var{objfile}@r{]}@r{]}@r{]}
If given, @var{provider} is a regular expression used to match against provider
names when selecting which probes to list. If omitted, probes by all
probes from all providers are listed.
If given, @var{name} is a regular expression to match against probe names
when selecting which probes to list. If omitted, probe names are not
considered when deciding whether to display them.
If given, @var{objfile} is a regular expression used to select which
object files (executable or shared libraries) to examine. If not
given, all object files are considered.
@item info probes all
List the available static probes, from all types.
@end table
@vindex $_probe_arg@r{, convenience variable}
A probe may specify up to twelve arguments. These are available at the
point at which the probe is defined---that is, when the current PC is
at the probe's location. The arguments are available using the
convenience variables (@pxref{Convenience Vars})
@code{$_probe_arg0}@dots{}@code{$_probe_arg11}. Each probe argument is
an integer of the appropriate size; types are not preserved. The
convenience variable @code{$_probe_argc} holds the number of arguments
at the current probe point.
These variables are always available, but attempts to access them at
any location other than a probe point will cause @value{GDBN} to give
an error message.
@c @ifclear BARETARGET @c @ifclear BARETARGET
@node Error in Breakpoints @node Error in Breakpoints
@subsection ``Cannot insert breakpoints'' @subsection ``Cannot insert breakpoints''
@ -6667,6 +6731,19 @@ specify the function unambiguously, e.g., if there are several
functions with identical names in different source files. functions with identical names in different source files.
@end table @end table
@cindex breakpoint at static probe point
@item -pstap|-probe-stap @r{[}@var{objfile}:@r{[}@var{provider}:@r{]}@r{]}@var{name}
The @sc{gnu}/Linux tool @code{SystemTap} provides a way for
applications to embed static probes. @xref{Static Probe Points}, for more
information on finding and using static probes. This form of linespec
specifies the location of such a static probe.
If @var{objfile} is given, only probes coming from that shared library
or executable matching @var{objfile} as a regular expression are considered.
If @var{provider} is given, then only probes from that provider are considered.
If several probes match the spec, @value{GDBN} will insert a breakpoint at
each one of those probes.
@end table @end table
@ -9071,6 +9148,10 @@ to match the format in which the data was printed.
The variable @code{$_exitcode} is automatically set to the exit code when The variable @code{$_exitcode} is automatically set to the exit code when
the program being debugged terminates. the program being debugged terminates.
@item $_probe_argc
@itemx $_probe_arg0@dots{}$_probe_arg11
Arguments to a static probe. @xref{Static Probe Points}.
@item $_sdata @item $_sdata
@vindex $_sdata@r{, inspect, convenience variable} @vindex $_sdata@r{, inspect, convenience variable}
The variable @code{$_sdata} contains extra collected static tracepoint The variable @code{$_sdata} contains extra collected static tracepoint
@ -11015,6 +11096,16 @@ Collect all local variables.
Collect the return address. This is helpful if you want to see more Collect the return address. This is helpful if you want to see more
of a backtrace. of a backtrace.
@item $_probe_argc
Collects the number of arguments from the static probe at which the
tracepoint is located.
@xref{Static Probe Points}.
@item $_probe_arg@var{n}
@var{n} is an integer between 0 and 11. Collects the @var{n}th argument
from the static probe at which the tracepoint is located.
@xref{Static Probe Points}.
@item $_sdata @item $_sdata
@vindex $_sdata@r{, collect} @vindex $_sdata@r{, collect}
Collect static tracepoint marker specific data. Only available for Collect static tracepoint marker specific data. Only available for

View File

@ -1,3 +1,15 @@
2012-04-27 Sergio Durigan Junior <sergiodj@redhat.com>
Tom Tromey <tromey@redhat.com>
* gdb.base/default.exp: Add `$_probe_arg*' convenience
variables.
* gdb.base/stap-probe.c: New file.
* gdb.base/stap-probe.exp: New file.
* gdb.trace/stap-trace.c: New file.
* gdb.trace/stap-trace.exp: New file.
* gdb.cp/nextoverthrow.exp: Add check for SystemTap probe in
libgcc's unwinder.
2012-04-26 Maciej W. Rozycki <macro@codesourcery.com> 2012-04-26 Maciej W. Rozycki <macro@codesourcery.com>
* gdb.arch/mips16-thunks-inmain.c: New file. * gdb.arch/mips16-thunks-inmain.c: New file.

View File

@ -604,6 +604,19 @@ gdb_test_list_exact "show convenience" "show convenience" \
{$_sdata = void} \ {$_sdata = void} \
{$_siginfo = void} \ {$_siginfo = void} \
{$_thread = 0} \ {$_thread = 0} \
{$_probe_argc = <error: No frame selected>} \
{$_probe_arg0 = <error: No frame selected>} \
{$_probe_arg1 = <error: No frame selected>} \
{$_probe_arg2 = <error: No frame selected>} \
{$_probe_arg3 = <error: No frame selected>} \
{$_probe_arg4 = <error: No frame selected>} \
{$_probe_arg5 = <error: No frame selected>} \
{$_probe_arg6 = <error: No frame selected>} \
{$_probe_arg7 = <error: No frame selected>} \
{$_probe_arg8 = <error: No frame selected>} \
{$_probe_arg9 = <error: No frame selected>} \
{$_probe_arg10 = <error: No frame selected>} \
{$_probe_arg11 = <error: No frame selected>} \
} }
#test show directories #test show directories

View File

@ -0,0 +1,108 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2012 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 USE_PROBES
#define _SDT_HAS_SEMAPHORES
__extension__ unsigned short test_user_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#define TEST test_user_semaphore
__extension__ unsigned short test_two_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#define TEST2 test_two_semaphore
__extension__ unsigned short test_m4_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
__extension__ unsigned short test_pstr_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
__extension__ unsigned short test_ps_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#else
#define TEST 1
#define TEST2 1
#endif
#include <sys/sdt.h>
/* We only support SystemTap and only the v3 form. */
#if _SDT_NOTE_TYPE != 3
#error "not using SystemTap v3 probes"
#endif
struct funcs
{
int val;
const char *(*ps) (int);
};
static void
m1 (void)
{
if (TEST2)
STAP_PROBE (test, two);
}
static void
m2 (void)
{
if (TEST2)
STAP_PROBE (test, two);
}
static int
f (int x)
{
if (TEST)
STAP_PROBE1 (test, user, x);
return x+5;
}
static const char *
pstr (int val)
{
const char *a = "This is a test message.";
const char *b = "This is another test message.";
STAP_PROBE3 (test, ps, a, b, val);
return val == 0 ? a : b;
}
static void
m4 (const struct funcs *fs, int v)
{
STAP_PROBE3 (test, m4, fs->val, fs->ps (v), v);
}
int
main()
{
struct funcs fs;
fs.val = 42;
fs.ps = pstr;
f (f (23));
m1 ();
m2 ();
m4 (&fs, 0);
m4 (&fs, 1);
return 0; /* last break here */
}

View File

@ -0,0 +1,183 @@
# Copyright (C) 2012 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/>.
set testfile stap-probe
# Run the tests. We run the tests two different ways: once with a
# plain probe, and once with a probe that has an associated semaphore.
# This returns -1 on failure to compile or start, 0 otherwise.
proc stap_test {exec_name {arg ""}} {
global testfile hex
if {[prepare_for_testing ${testfile}.exp ${exec_name} ${testfile}.c \
[concat $arg debug]]} {
return -1
}
if ![runto_main] {
return -1
}
gdb_test "print \$_probe_argc" "No SystemTap probe at PC $hex" \
"check argument not at probe point"
gdb_test "info probes stap" \
"test *user *$hex .*" \
"info probes stap"
if {[runto "-pstap test:user"]} {
pass "run to -pstap test:user"
} else {
fail "run to -pstap test:user"
}
# Test probe arguments.
gdb_test "print \$_probe_argc" " = 1" \
"print \$_probe_argc for probe user"
gdb_test "print \$_probe_arg0 == x" " = 1" \
"check \$_probe_arg0 for probe user"
gdb_test "print \$_probe_arg1" \
"Invalid probe argument 1 -- probe has 1 arguments available" \
"check \$_probe_arg1 for probe user"
# Set a breakpoint with multiple probe locations.
gdb_test "break -pstap test:two" \
"Breakpoint \[0-9\]+ at $hex.*2 locations.*" \
"set multi-location probe breakpoint (probe two)"
# Reinit GDB, set a breakpoint on probe m4.
delete_breakpoints
rerun_to_main
if {[runto "-pstap test:m4"]} {
pass "run to -pstap test:m4"
} else {
fail "run to -pstap test:m4"
}
# Testing probe arguments.
gdb_test "print \$_probe_argc" " = 3" \
"print \$_probe_argc for probe m4"
gdb_test "print \$_probe_arg0" " = 42" \
"check \$_probe_arg0 for probe m4"
gdb_test "print (const char *) \$_probe_arg1" \
" = $hex .This is a test message.*" \
"check \$_probe_arg1 for probe m4"
gdb_test "print \$_probe_arg2 == v" " = 1" \
"check \$_probe_arg2 for probe m4"
# Reinit GDB, set a breakpoint on probe ps.
delete_breakpoints
rerun_to_main
if {[runto "-pstap test:ps"]} {
pass "run to -pstap test:m4"
} else {
fail "run to -pstap test:m4"
}
gdb_test "print \$_probe_argc" " = 3" \
"print \$_probe_argc for probe ps"
gdb_test "print (const char *) \$_probe_arg1" \
" = $hex .This is another test message.*" \
"print \$_probe_arg1 for probe ps"
return 0
}
proc stap_test_no_debuginfo {exec_name {arg ""}} {
global testfile hex
if {[prepare_for_testing ${testfile}.exp ${exec_name} ${testfile}.c \
{$arg nodebug optimize=-O2}]} {
return -1
}
if {[runto "-pstap test:user"]} {
pass "run to -pstap test:user"
} else {
fail "run to -pstap test:user"
}
# Test probe arguments.
gdb_test "print \$_probe_argc" " = 1" \
"print \$_probe_argc for probe user"
gdb_test "print \$_probe_arg0 == 23" " = 1" \
"check \$_probe_arg0 for probe user"
gdb_test "print \$_probe_arg1" \
"Invalid probe argument 1 -- probe has 1 arguments available" \
"check \$_probe_arg1 for probe user"
# Set a breakpoint with multiple probe locations.
# In this scenario, we may expect more than 2 locations because of
# the optimizations (inlining, loop unrolling, etc).
gdb_test "break -pstap test:two" \
"Breakpoint .* at $hex.*\[0-9\]+ locations.*" \
"set multi-location probe breakpoint (probe two)"
# Reinit GDB, set a breakpoint on probe m4.
delete_breakpoints
rerun_to_main
if {[runto "-pstap test:m4"]} {
pass "run to -pstap test:m4"
} else {
fail "run to -pstap test:m4"
}
# Testing probe arguments.
gdb_test "print \$_probe_argc" " = 3" \
"print \$_probe_argc for probe m4"
gdb_test "print \$_probe_arg0" " = 42" \
"check \$_probe_arg0 for probe m4"
gdb_test "print (const char *) \$_probe_arg1" \
" = $hex .This is a test message.*" \
"check \$_probe_arg1 for probe m4"
gdb_test "print \$_probe_arg2 == 0" " = 1" \
"check \$_probe_arg2 for probe m4"
# Reinit GDB, set a breakpoint on probe ps.
delete_breakpoints
rerun_to_main
if {[runto "-pstap test:ps"]} {
pass "run to -pstap test:m4"
} else {
fail "run to -pstap test:m4"
}
gdb_test "print \$_probe_argc" " = 3" \
"print \$_probe_argc for probe ps"
gdb_test "print (const char *) \$_probe_arg1" \
" = $hex .This is another test message.*" \
"print \$_probe_arg1 for probe ps"
return 0
}
with_test_prefix "without semaphore, not optimized" {
if {[stap_test "stap-probe-nosem-noopt"] == -1} {
untested stap-probe.exp
return -1
}
}
with_test_prefix "with semaphore, not optimized" {
stap_test "stap-probe-sem-noopt" "-DUSE_PROBES"
}
with_test_prefix "without semaphore, optimized" {
stap_test_no_debuginfo "stap-probe-nosem-opt"
}
with_test_prefix "with semaphore, optimized" {
stap_test_no_debuginfo "stap-probe-sem-opt" "-DUSE_PROBES"
}

View File

@ -53,6 +53,17 @@ gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook" {
set ok 0 set ok 0
} }
} }
if {!$ok} {
gdb_test_multiple "info probe" "check for stap probe in unwinder" {
-re ".*libgcc.*unwind.*\r\n$gdb_prompt $" {
pass "check for stap probe in unwinder"
set ok 1
}
-re "\r\n$gdb_prompt $" {
}
}
}
if {!$ok} { if {!$ok} {
unsupported "nextoverthrow.exp could not find _Unwind_DebugHook" unsupported "nextoverthrow.exp could not find _Unwind_DebugHook"
return -1 return -1

View File

@ -0,0 +1,71 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2012 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 USE_PROBES
#define _SDT_HAS_SEMAPHORES
__extension__ unsigned short test_user_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#define TEST test_user_semaphore
__extension__ unsigned short test_two_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#define TEST2 test_two_semaphore
#else
#define TEST 1
#define TEST2 1
#endif /* USE_PROBES */
#include <sys/sdt.h>
/* We only support SystemTap and only the v3 form. */
#if _SDT_NOTE_TYPE != 3
#error "not using SystemTap v3 probes"
#endif
void
m1 (int x)
{
if (TEST2)
STAP_PROBE1 (test, two, x);
}
int
f (int x)
{
if (TEST)
STAP_PROBE1(test, user, x);
return x+5;
}
void
nothing (void)
{
int a = 1 + 1;
return;
}
int
main()
{
f (f (23));
m1 (46);
nothing (); /* end-here */
return 0;
}

View File

@ -0,0 +1,128 @@
# Copyright 2012 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 "stap-trace"
set srcfile ${testfile}.c
set executable ""
set binfile_dir $objdir/$subdir
set ws "\[\r\n\t \]+"
set cr "\[\r\n\]+"
# Only x86 and x86_64 targets are supported for now.
if { ![istarget "x86_64-*"] && ![istarget "i?86-*"] } {
continue
}
proc compile_stap_bin {exec_name {arg ""}} {
global srcfile
global binfile_dir
global srcdir
global subdir
global executable
if { $arg != "" } {
set arg "additional_flags=$arg"
}
set executable ${exec_name}
if { [gdb_compile "$srcdir/$subdir/$srcfile" \
"$binfile_dir/$exec_name" \
executable [concat $arg debug nowarnings]] != "" } {
untested "Could not compile ${srcfile}"
return -1
}
}
proc prepare_for_trace_test {} {
global executable
clean_restart $executable
if { ![runto_main] } {
perror "Could not run to `main'."
continue
}
gdb_breakpoint [gdb_get_line_number "end-here"]
}
proc run_trace_experiment { test_probe msg } {
global gdb_prompt
set test "collect $msg: start trace experiment"
gdb_test_multiple "tstart" "$test" {
-re "^tstart\r\n$gdb_prompt $" {
pass "$test"
}
}
gdb_test "continue" \
"Continuing.*Breakpoint \[0-9\]+.*" \
"collect $msg: run trace experiment"
gdb_test "tstop" \
"\[\r\n\]+" \
"collect $msg: stop trace experiment"
gdb_test "tfind start" \
"#0 .*" \
"collect $msg: tfind test frame"
}
proc gdb_collect_probe_arg { msg probe val_arg0 } {
global gdb_prompt
global cr
prepare_for_trace_test
gdb_test "trace $probe" \
"Tracepoint \[0-9\]+ at .*" \
"collect $msg: set tracepoint"
gdb_trace_setactions "collect $msg: define actions" \
"" \
"collect \$_probe_arg0" "^$"
# Begin the test.
run_trace_experiment $msg $probe
gdb_test "print \$_probe_arg0" \
"\\$\[0-9\]+ = $val_arg0$cr" \
"collect $msg: collected probe arg0"
}
compile_stap_bin "stap-probe-nosem"
clean_restart $executable
if { ![runto_main] } {
perror "Could not run to `main'."
continue
}
if { ![gdb_target_supports_trace] } {
# Test cannot run on this target.
return 1;
}
gdb_collect_probe_arg "probe args without semaphore" "-probe-stap user" "23"
gdb_exit
compile_stap_bin "stap-probe-sem" "-DUSE_PROBES"
gdb_collect_probe_arg "probe args with semaphore" "-probe-stap two" "46"
# Finished!
gdb_test "tfind none" ".*" ""