python: Add qualified parameter to gdb.Breakpoint
This patch adds the possibility to pass a qualified=True|False parameter when creating a breakpoint in Python. It is equivalent to using -qualified in a linespec. The parameter actually accepts any Python value, and converts it to boolean using Python's standard rules for that (https://docs.python.org/3/library/stdtypes.html#truth). Unlike the -source/-line/-function/-label parameters, it is possible to use -qualified with a "normal" (non-explicit) linespec. Therefore, it is possible (unlike these other parameters) to use this new parameter along with the spec parameter. I updated the py-breakpoint.exp test. To be able to test multiple locations using a namespace, I had to switch the test case to compile as C++. If we really wanted to, we could run it as both C and C++, but omit the C++-specific parts when running it as C. gdb/ChangeLog: * location.h (string_to_event_location): Add match_type parameter. * location.c (string_to_event_location): Likewise. * python/py-breakpoint.c (bppy_init): Handle qualified parameter. gdb/doc/ChangeLog: * python.texi (Manipulating breakpoints using Python): Document qualified parameter to gdb.Breakpoint. gdb/testsuite/ChangeLog: * gdb.python/py-breakpoint.c (foo_ns::multiply): New function. * gdb.python/py-breakpoint.exp: Compile the test case as c++, call test_bkpt_qualified. (test_bkpt_qualified): New proc.
This commit is contained in:
parent
6892d2e4df
commit
b89641bab5
@ -1,3 +1,11 @@
|
||||
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* location.h (string_to_event_location): Add match_type
|
||||
parameter.
|
||||
* location.c (string_to_event_location): Likewise.
|
||||
* python/py-breakpoint.c (bppy_init): Handle qualified
|
||||
parameter.
|
||||
|
||||
2017-12-13 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* completer.c (completion_tracker::maybe_add_completion): New
|
||||
|
4
gdb/NEWS
4
gdb/NEWS
@ -81,7 +81,9 @@
|
||||
GDB interpret the specified function name as a complete
|
||||
fully-qualified name instead. For example, using the same C++
|
||||
program, the "break -q B::func" command sets a breakpoint on
|
||||
"B::func", only.
|
||||
"B::func", only. A parameter has been added to the Python
|
||||
gdb.Breakpoint constructor to achieve the same result when creating
|
||||
a breakpoint from Python.
|
||||
|
||||
* Breakpoints on functions marked with C++ ABI tags
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* python.texi (Manipulating breakpoints using Python): Document
|
||||
qualified parameter to gdb.Breakpoint.
|
||||
|
||||
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* python.texi (Manipulating breakpoints using Python): Split doc
|
||||
|
@ -4887,7 +4887,7 @@ create both breakpoints and watchpoints. The second accepts separate Python
|
||||
arguments similar to @ref{Explicit Locations}, and can only be used to create
|
||||
breakpoints.
|
||||
|
||||
@defun Breakpoint.__init__ (spec @r{[}, type @r{][}, wp_class @r{][}, internal @r{][}, temporary @r{]})
|
||||
@defun Breakpoint.__init__ (spec @r{[}, type @r{][}, wp_class @r{][}, internal @r{][}, temporary @r{][}, qualified @r{]})
|
||||
Create a new breakpoint according to @var{spec}, which is a string naming the
|
||||
location of a breakpoint, or an expression that defines a watchpoint. The
|
||||
string should describe a location in a format recognized by the @code{break}
|
||||
@ -4911,15 +4911,22 @@ The optional @var{temporary} argument makes the breakpoint a temporary
|
||||
breakpoint. Temporary breakpoints are deleted after they have been hit. Any
|
||||
further access to the Python breakpoint after it has been hit will result in a
|
||||
runtime error (as that breakpoint has now been automatically deleted).
|
||||
|
||||
The optional @var{qualified} argument is a boolean that allows interpreting
|
||||
the function passed in @code{spec} as a fully-qualified name. It is equivalent
|
||||
to @code{break}'s @code{-qualified} flag (@pxref{Linespec Locations} and
|
||||
@ref{Explicit Locations}).
|
||||
|
||||
@end defun
|
||||
|
||||
@defun Breakpoint.__init__ (@r{[} source @r{][}, function @r{][}, label @r{][}, line @r{]}, @r{][} internal @r{][}, temporary @r{]})
|
||||
@defun Breakpoint.__init__ (@r{[} source @r{][}, function @r{][}, label @r{][}, line @r{]}, @r{][} internal @r{][}, temporary @r{][}, qualified @r{]})
|
||||
This second form of creating a new breakpoint specifies the explicit
|
||||
location (@pxref{Explicit Locations}) using keywords. The new breakpoint will
|
||||
be created in the specified source file @var{source}, at the specified
|
||||
@var{function}, @var{label} and @var{line}.
|
||||
|
||||
@var{internal} and @var{temporary} have the same usage as explained previously.
|
||||
@var{internal}, @var{temporary} and @var{qualified} have the same usage as
|
||||
explained previously.
|
||||
@end defun
|
||||
|
||||
The available types are represented by constants defined in the @code{gdb}
|
||||
|
@ -915,10 +915,10 @@ string_to_event_location_basic (const char **stringp,
|
||||
|
||||
event_location_up
|
||||
string_to_event_location (const char **stringp,
|
||||
const struct language_defn *language)
|
||||
const struct language_defn *language,
|
||||
symbol_name_match_type match_type)
|
||||
{
|
||||
const char *arg, *orig;
|
||||
symbol_name_match_type match_type = symbol_name_match_type::WILD;
|
||||
|
||||
/* Try an explicit location. */
|
||||
orig = arg = *stringp;
|
||||
|
@ -220,11 +220,14 @@ extern event_location_up
|
||||
This function is intended to be used by CLI commands and will parse
|
||||
explicit locations in a CLI-centric way. Other interfaces should use
|
||||
string_to_event_location_basic if they want to maintain support for
|
||||
legacy specifications of probe, address, and linespec locations. */
|
||||
legacy specifications of probe, address, and linespec locations.
|
||||
|
||||
extern event_location_up
|
||||
string_to_event_location (const char **argp,
|
||||
const struct language_defn *langauge);
|
||||
MATCH_TYPE should be either WILD or FULL. If -q/--qualified is specified
|
||||
in the input string, it will take precedence over this parameter. */
|
||||
|
||||
extern event_location_up string_to_event_location
|
||||
(const char **argp, const struct language_defn *langauge,
|
||||
symbol_name_match_type match_type = symbol_name_match_type::WILD);
|
||||
|
||||
/* Like string_to_event_location, but does not attempt to parse
|
||||
explicit locations. MATCH_TYPE indicates how function names should
|
||||
|
@ -694,7 +694,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static const char *keywords[] = { "spec", "type", "wp_class", "internal",
|
||||
"temporary","source", "function",
|
||||
"label", "line", NULL };
|
||||
"label", "line", "qualified", NULL };
|
||||
const char *spec = NULL;
|
||||
enum bptype type = bp_breakpoint;
|
||||
int access_type = hw_write;
|
||||
@ -707,12 +707,14 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
char *label = NULL;
|
||||
char *source = NULL;
|
||||
char *function = NULL;
|
||||
int qualified = 0;
|
||||
|
||||
if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|siiOOsssO", keywords,
|
||||
if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|siiOOsssOp", keywords,
|
||||
&spec, &type, &access_type,
|
||||
&internal,
|
||||
&temporary, &source,
|
||||
&function, &label, &lineobj))
|
||||
&function, &label, &lineobj,
|
||||
&qualified))
|
||||
return -1;
|
||||
|
||||
|
||||
@ -759,6 +761,10 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
case bp_breakpoint:
|
||||
{
|
||||
event_location_up location;
|
||||
symbol_name_match_type func_name_match_type
|
||||
= (qualified
|
||||
? symbol_name_match_type::FULL
|
||||
: symbol_name_match_type::WILD);
|
||||
|
||||
if (spec != NULL)
|
||||
{
|
||||
@ -767,7 +773,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
const char *copy = copy_holder.get ();
|
||||
|
||||
location = string_to_event_location (©,
|
||||
current_language);
|
||||
current_language,
|
||||
func_name_match_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -782,6 +789,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
explicit_loc.line_offset =
|
||||
linespec_parse_line_offset (line.get ());
|
||||
|
||||
explicit_loc.func_name_match_type = func_name_match_type;
|
||||
|
||||
location = new_explicit_location (&explicit_loc);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
2017-12-13 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* gdb.python/py-breakpoint.c (foo_ns::multiply): New function.
|
||||
* gdb.python/py-breakpoint.exp: Compile the test case as c++,
|
||||
call test_bkpt_qualified.
|
||||
(test_bkpt_qualified): New proc.
|
||||
|
||||
2017-12-13 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* lib/completion-support.exp (test_gdb_complete_tab_multiple):
|
||||
|
@ -17,6 +17,14 @@
|
||||
|
||||
int result = 0;
|
||||
|
||||
namespace foo_ns
|
||||
{
|
||||
int multiply (int i)
|
||||
{
|
||||
return i * i;
|
||||
}
|
||||
}
|
||||
|
||||
int multiply (int i)
|
||||
{
|
||||
return i * i;
|
||||
|
@ -20,7 +20,9 @@ load_lib gdb-python.exp
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
|
||||
set options {debug c++}
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} ${options}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
@ -608,6 +610,77 @@ proc_with_prefix test_bkpt_explicit_loc {} {
|
||||
"set invalid explicit breakpoint by missing function"
|
||||
}
|
||||
|
||||
proc_with_prefix test_bkpt_qualified {} {
|
||||
global decimal hex testfile
|
||||
|
||||
# Start with a fresh gdb.
|
||||
clean_restart ${testfile}
|
||||
|
||||
set one_location_re "Breakpoint $decimal at $hex:.*line $decimal."
|
||||
set two_location_re "Breakpoint $decimal at $hex:.*2 locations."
|
||||
|
||||
if ![runto_main] then {
|
||||
fail "cannot run to main."
|
||||
return 0
|
||||
}
|
||||
|
||||
# Test the default value of "qualified".
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(\"multiply\")" \
|
||||
$two_location_re \
|
||||
"qualified implicitly false"
|
||||
|
||||
# Test qualified=False.
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(\"multiply\", qualified=False)" \
|
||||
$two_location_re \
|
||||
"qualified false"
|
||||
|
||||
# Test qualified=True.
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(\"multiply\", qualified=True)" \
|
||||
$one_location_re \
|
||||
"qualified true"
|
||||
|
||||
# Test qualified=True with an explicit function.
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(function=\"multiply\", qualified=True)" \
|
||||
$one_location_re \
|
||||
"qualified true and explicit"
|
||||
|
||||
# Test qualified=False with an explicit function.
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(function=\"multiply\", qualified=False)" \
|
||||
$two_location_re \
|
||||
"qualified false and explicit"
|
||||
|
||||
# Test -q in the spec string.
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(\"-q multiply\")" \
|
||||
$one_location_re \
|
||||
"-q in spec string"
|
||||
|
||||
# Test -q in the spec string with explicit location.
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(\"-q -function multiply\")" \
|
||||
$one_location_re \
|
||||
"-q in spec string with explicit location"
|
||||
|
||||
# Test -q in the spec string and qualified=False (-q should win).
|
||||
delete_breakpoints
|
||||
gdb_test \
|
||||
"python gdb.Breakpoint(\"-q multiply\", qualified=False)" \
|
||||
$one_location_re \
|
||||
"-q in spec string and qualified false"
|
||||
}
|
||||
|
||||
test_bkpt_basic
|
||||
test_bkpt_deletion
|
||||
test_bkpt_cond_and_cmds
|
||||
@ -620,3 +693,4 @@ test_bkpt_address
|
||||
test_bkpt_pending
|
||||
test_bkpt_events
|
||||
test_bkpt_explicit_loc
|
||||
test_bkpt_qualified
|
||||
|
Loading…
Reference in New Issue
Block a user