Add $_memeq, $_regex, $_streq, $_strlen convenience functions.
* NEWS: Document them. * data-directory/Makefile.in (PYTHON_FILES): Add function/__init__.py, function/strfns.py. * python/py-type.c (typy_array_1): New function. (typy_array): Call it. (typy_vector): New function. (type_object_methods): Add "vector". * python/lib/gdb/function/__init__.py: New file. * python/lib/gdb/function/strfns.py: New file. doc/ * gdb.texinfo (Convenience Funs): New node. (Types In Python): Document Type.vector. testsuite/ * gdb.python/py-strfns.c: New file. * gdb.python/py-strfns.exp: New file. * gdb.python/py-type.exp (test_fields): Add vector tests.
This commit is contained in:
parent
200bc880f4
commit
a72c32530e
12 changed files with 405 additions and 3 deletions
|
@ -1,3 +1,16 @@
|
||||||
|
2012-08-10 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
Add $_memeq, $_regex, $_streq, $_strlen convenience functions.
|
||||||
|
* NEWS: Document them.
|
||||||
|
* data-directory/Makefile.in (PYTHON_FILES): Add function/__init__.py,
|
||||||
|
function/strfns.py.
|
||||||
|
* python/py-type.c (typy_array_1): New function.
|
||||||
|
(typy_array): Call it.
|
||||||
|
(typy_vector): New function.
|
||||||
|
(type_object_methods): Add "vector".
|
||||||
|
* python/lib/gdb/function/__init__.py: New file.
|
||||||
|
* python/lib/gdb/function/strfns.py: New file.
|
||||||
|
|
||||||
2012-08-10 Siddhesh Poyarekar <siddhesh@redhat.com>
|
2012-08-10 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
* python/py-type.c (convert_field): Use gdb_py_long_from_longest
|
* python/py-type.c (convert_field): Use gdb_py_long_from_longest
|
||||||
|
|
11
gdb/NEWS
11
gdb/NEWS
|
@ -3,6 +3,17 @@
|
||||||
|
|
||||||
*** Changes since GDB 7.5
|
*** Changes since GDB 7.5
|
||||||
|
|
||||||
|
* Python scripting
|
||||||
|
|
||||||
|
** Vectors can be created with gdb.Type.vector.
|
||||||
|
|
||||||
|
* New Python-based convenience functions:
|
||||||
|
|
||||||
|
** $_memeq(buf1, buf2, length)
|
||||||
|
** $_streq(str1, str2)
|
||||||
|
** $_strlen(str)
|
||||||
|
** $_regex(str, regex)
|
||||||
|
|
||||||
* The 'cd' command now defaults to using '~' (the home directory) if not
|
* The 'cd' command now defaults to using '~' (the home directory) if not
|
||||||
given an argument.
|
given an argument.
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,9 @@ PYTHON_FILES = \
|
||||||
gdb/command/__init__.py \
|
gdb/command/__init__.py \
|
||||||
gdb/command/pretty_printers.py \
|
gdb/command/pretty_printers.py \
|
||||||
gdb/command/prompt.py \
|
gdb/command/prompt.py \
|
||||||
gdb/command/explore.py
|
gdb/command/explore.py \
|
||||||
|
gdb/function/__init__.py \
|
||||||
|
gdb/function/strfns.py
|
||||||
|
|
||||||
FLAGS_TO_PASS = \
|
FLAGS_TO_PASS = \
|
||||||
"prefix=$(prefix)" \
|
"prefix=$(prefix)" \
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2012-08-10 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
* gdb.texinfo (Convenience Funs): New node.
|
||||||
|
(Types In Python): Document Type.vector.
|
||||||
|
|
||||||
2012-08-09 Yao Qi <yao@codesourcery.com>
|
2012-08-09 Yao Qi <yao@codesourcery.com>
|
||||||
|
|
||||||
* observer.texi: New observer command_param_changed.
|
* observer.texi: New observer command_param_changed.
|
||||||
|
|
|
@ -7558,6 +7558,7 @@ being passed the type of @var{arg} as the argument.
|
||||||
* Pretty Printing:: Python pretty printing
|
* Pretty Printing:: Python pretty printing
|
||||||
* Value History:: Value history
|
* Value History:: Value history
|
||||||
* Convenience Vars:: Convenience variables
|
* Convenience Vars:: Convenience variables
|
||||||
|
* Convenience Funs:: Convenience functions
|
||||||
* Registers:: Registers
|
* Registers:: Registers
|
||||||
* Floating Point Hardware:: Floating point hardware
|
* Floating Point Hardware:: Floating point hardware
|
||||||
* Vector Unit:: Vector Unit
|
* Vector Unit:: Vector Unit
|
||||||
|
@ -9311,6 +9312,9 @@ On HP-UX systems, if you refer to a function or variable name that
|
||||||
begins with a dollar sign, @value{GDBN} searches for a user or system
|
begins with a dollar sign, @value{GDBN} searches for a user or system
|
||||||
name first, before it searches for a convenience variable.
|
name first, before it searches for a convenience variable.
|
||||||
|
|
||||||
|
@node Convenience Funs
|
||||||
|
@section Convenience Functions
|
||||||
|
|
||||||
@cindex convenience functions
|
@cindex convenience functions
|
||||||
@value{GDBN} also supplies some @dfn{convenience functions}. These
|
@value{GDBN} also supplies some @dfn{convenience functions}. These
|
||||||
have a syntax similar to convenience variables. A convenience
|
have a syntax similar to convenience variables. A convenience
|
||||||
|
@ -9318,6 +9322,38 @@ function can be used in an expression just like an ordinary function;
|
||||||
however, a convenience function is implemented internally to
|
however, a convenience function is implemented internally to
|
||||||
@value{GDBN}.
|
@value{GDBN}.
|
||||||
|
|
||||||
|
These functions require @value{GDBN} to be configured with
|
||||||
|
@code{Python} support.
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item $_memeq(@var{buf1}, @var{buf2}, @var{length})
|
||||||
|
@findex $_memeq@r{, convenience function}
|
||||||
|
Returns one if the @var{length} bytes at the addresses given by
|
||||||
|
@var{buf1} and @var{buf2} are equal.
|
||||||
|
Otherwise it returns zero.
|
||||||
|
|
||||||
|
@item $_regex(@var{str}, @var{regex})
|
||||||
|
@findex $_regex@r{, convenience function}
|
||||||
|
Returns one if the string @var{str} matches the regular expression
|
||||||
|
@var{regex}. Otherwise it returns zero.
|
||||||
|
The syntax of the regular expression is that specified by @code{Python}'s
|
||||||
|
regular expression support.
|
||||||
|
|
||||||
|
@item $_streq(@var{str1}, @var{str2})
|
||||||
|
@findex $_streq@r{, convenience function}
|
||||||
|
Returns one if the strings @var{str1} and @var{str2} are equal.
|
||||||
|
Otherwise it returns zero.
|
||||||
|
|
||||||
|
@item $_strlen(@var{str})
|
||||||
|
@findex $_strlen@r{, convenience function}
|
||||||
|
Returns the length of string @var{str}.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@value{GDBN} provides the ability to list and get help on
|
||||||
|
convenience functions.
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item help function
|
@item help function
|
||||||
@kindex help function
|
@kindex help function
|
||||||
|
@ -23361,6 +23397,19 @@ second argument is the upper bound of the array. An array's length
|
||||||
must not be negative, but the bounds can be.
|
must not be negative, but the bounds can be.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
|
@defun Type.vector (@var{n1} @r{[}, @var{n2}@r{]})
|
||||||
|
Return a new @code{gdb.Type} object which represents a vector of this
|
||||||
|
type. If one argument is given, it is the inclusive upper bound of
|
||||||
|
the vector; in this case the lower bound is zero. If two arguments are
|
||||||
|
given, the first argument is the lower bound of the vector, and the
|
||||||
|
second argument is the upper bound of the vector. A vector's length
|
||||||
|
must not be negative, but the bounds can be.
|
||||||
|
|
||||||
|
The difference between an @code{array} and a @code{vector} is that
|
||||||
|
arrays behave like in C: when used in expressions they decay to a pointer
|
||||||
|
to the first element whereas vectors are treated as first class values.
|
||||||
|
@end defun
|
||||||
|
|
||||||
@defun Type.const ()
|
@defun Type.const ()
|
||||||
Return a new @code{gdb.Type} object which represents a
|
Return a new @code{gdb.Type} object which represents a
|
||||||
@code{const}-qualified variant of this type.
|
@code{const}-qualified variant of this type.
|
||||||
|
|
14
gdb/python/lib/gdb/function/__init__.py
Normal file
14
gdb/python/lib/gdb/function/__init__.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# 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/>.
|
108
gdb/python/lib/gdb/function/strfns.py
Normal file
108
gdb/python/lib/gdb/function/strfns.py
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
# Useful gdb string convenience functions.
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
"""$_memeq, $_strlen, $_streq, $_regex"""
|
||||||
|
|
||||||
|
import gdb
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class _MemEq(gdb.Function):
|
||||||
|
"""$_memeq - compare bytes of memory
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
$_memeq(a, b, len)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if len bytes at a and b compare equally.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
super(_MemEq, self).__init__("_memeq")
|
||||||
|
|
||||||
|
def invoke(self, a, b, length):
|
||||||
|
if length < 0:
|
||||||
|
raise ValueError("length must be non-negative")
|
||||||
|
if length == 0:
|
||||||
|
return True
|
||||||
|
# The argument(s) to vector are [low_bound,]high_bound.
|
||||||
|
byte_vector = gdb.lookup_type("char").vector(length - 1)
|
||||||
|
ptr_byte_vector = byte_vector.pointer()
|
||||||
|
a_ptr = a.reinterpret_cast(ptr_byte_vector)
|
||||||
|
b_ptr = b.reinterpret_cast(ptr_byte_vector)
|
||||||
|
return a_ptr.dereference() == b_ptr.dereference()
|
||||||
|
|
||||||
|
|
||||||
|
class _StrLen(gdb.Function):
|
||||||
|
"""$_strlen - compute string length
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
$_strlen(a)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Length of string a, assumed to be a string in the current language.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
super(_StrLen, self).__init__("_strlen")
|
||||||
|
|
||||||
|
def invoke(self, a):
|
||||||
|
s = a.string()
|
||||||
|
return len(s)
|
||||||
|
|
||||||
|
|
||||||
|
class _StrEq(gdb.Function):
|
||||||
|
"""$_streq - check string equality
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
$_streq(a, b)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if a and b are identical strings in the current language.
|
||||||
|
|
||||||
|
Example (amd64-linux):
|
||||||
|
catch syscall open
|
||||||
|
cond $bpnum $_streq((char*) $rdi, "foo")
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
super(_StrEq, self).__init__("_streq")
|
||||||
|
|
||||||
|
def invoke(self, a, b):
|
||||||
|
return a.string() == b.string()
|
||||||
|
|
||||||
|
|
||||||
|
class _RegEx(gdb.Function):
|
||||||
|
"""$_regex - check if a string matches a regular expression
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
$_regex(string, regex)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if string str (in the current language) matches the
|
||||||
|
regular expression regex.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
super(_RegEx, self).__init__("_regex")
|
||||||
|
|
||||||
|
def invoke(self, string, regex):
|
||||||
|
s = string.string()
|
||||||
|
r = re.compile(regex.string())
|
||||||
|
return bool(r.match(s))
|
||||||
|
|
||||||
|
|
||||||
|
# GDB will import us automagically via gdb/__init__.py.
|
||||||
|
_MemEq()
|
||||||
|
_StrLen()
|
||||||
|
_StrEq()
|
||||||
|
_RegEx()
|
|
@ -461,10 +461,10 @@ typy_get_composite (struct type *type)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return an array type. */
|
/* Helper for typy_array and typy_vector. */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typy_array (PyObject *self, PyObject *args)
|
typy_array_1 (PyObject *self, PyObject *args, int is_vector)
|
||||||
{
|
{
|
||||||
long n1, n2;
|
long n1, n2;
|
||||||
PyObject *n2_obj = NULL;
|
PyObject *n2_obj = NULL;
|
||||||
|
@ -503,12 +503,30 @@ typy_array (PyObject *self, PyObject *args)
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
array = lookup_array_range_type (type, n1, n2);
|
array = lookup_array_range_type (type, n1, n2);
|
||||||
|
if (is_vector)
|
||||||
|
make_vector_type (array);
|
||||||
}
|
}
|
||||||
GDB_PY_HANDLE_EXCEPTION (except);
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
return type_to_type_object (array);
|
return type_to_type_object (array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return an array type. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
typy_array (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
return typy_array_1 (self, args, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a vector type. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
typy_vector (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
return typy_array_1 (self, args, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return a Type object which represents a pointer to SELF. */
|
/* Return a Type object which represents a pointer to SELF. */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typy_pointer (PyObject *self, PyObject *args)
|
typy_pointer (PyObject *self, PyObject *args)
|
||||||
|
@ -1559,6 +1577,14 @@ static PyMethodDef type_object_methods[] =
|
||||||
Return a type which represents an array of objects of this type.\n\
|
Return a type which represents an array of objects of this type.\n\
|
||||||
The bounds of the array are [LOW_BOUND, HIGH_BOUND] inclusive.\n\
|
The bounds of the array are [LOW_BOUND, HIGH_BOUND] inclusive.\n\
|
||||||
If LOW_BOUND is omitted, a value of zero is used." },
|
If LOW_BOUND is omitted, a value of zero is used." },
|
||||||
|
{ "vector", typy_vector, METH_VARARGS,
|
||||||
|
"vector ([LOW_BOUND,] HIGH_BOUND) -> Type\n\
|
||||||
|
Return a type which represents a vector of objects of this type.\n\
|
||||||
|
The bounds of the array are [LOW_BOUND, HIGH_BOUND] inclusive.\n\
|
||||||
|
If LOW_BOUND is omitted, a value of zero is used.\n\
|
||||||
|
Vectors differ from arrays in that if the current language has C-style\n\
|
||||||
|
arrays, vectors don't decay to a pointer to the first element.\n\
|
||||||
|
They are first class values." },
|
||||||
{ "__contains__", typy_has_key, METH_VARARGS,
|
{ "__contains__", typy_has_key, METH_VARARGS,
|
||||||
"T.__contains__(k) -> True if T has a field named k, else False" },
|
"T.__contains__(k) -> True if T has a field named k, else False" },
|
||||||
{ "const", typy_const, METH_NOARGS,
|
{ "const", typy_const, METH_NOARGS,
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2012-08-10 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
* gdb.python/py-strfns.c: New file.
|
||||||
|
* gdb.python/py-strfns.exp: New file.
|
||||||
|
* gdb.python/py-type.exp (test_fields): Add vector tests.
|
||||||
|
|
||||||
2012-08-10 Mike Frysinger <vapier@gentoo.org>
|
2012-08-10 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
PR cli/10436:
|
PR cli/10436:
|
||||||
|
|
50
gdb/testsuite/gdb.python/py-strfns.c
Normal file
50
gdb/testsuite/gdb.python/py-strfns.c
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/* 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/>. */
|
||||||
|
|
||||||
|
const char str1[] = "Hello.";
|
||||||
|
const char str2[] = "Hello.";
|
||||||
|
const char str3[] = "Goodbye.";
|
||||||
|
|
||||||
|
const char buf1[] = { 0, 1, 2, 3 };
|
||||||
|
const char buf2[] = { 0, 1, 2, 3 };
|
||||||
|
const char buf3[] = { 0, 1, 2, 4 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
func (const char *arg)
|
||||||
|
{
|
||||||
|
return; /* Break func here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bfunc (const char *arg)
|
||||||
|
{
|
||||||
|
return; /* Break bfunc here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
func (str1);
|
||||||
|
func (str2);
|
||||||
|
func (str3);
|
||||||
|
|
||||||
|
bfunc (buf1);
|
||||||
|
bfunc (buf2);
|
||||||
|
bfunc (buf3);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
103
gdb/testsuite/gdb.python/py-strfns.exp
Normal file
103
gdb/testsuite/gdb.python/py-strfns.exp
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
# This file is part of the GDB testsuite. It tests the convenience
|
||||||
|
# functions in strfns.py.
|
||||||
|
|
||||||
|
load_lib gdb-python.exp
|
||||||
|
|
||||||
|
standard_testfile
|
||||||
|
|
||||||
|
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ![runto_main] {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Skip all tests if Python scripting is not enabled.
|
||||||
|
if { [skip_python_tests] } { continue }
|
||||||
|
|
||||||
|
proc test_all_strfns { } {
|
||||||
|
gdb_test "p \$_streq (str1, str2)" " = 1"
|
||||||
|
gdb_test "p \$_streq (str1, str3)" " = 0"
|
||||||
|
|
||||||
|
gdb_test "p \$_strlen (str1)" " = 6"
|
||||||
|
gdb_test "p \$_strlen (buf1)" " = 0"
|
||||||
|
|
||||||
|
gdb_test "p \$_memeq (buf1, buf2, 4)" " = 1"
|
||||||
|
gdb_test "p \$_memeq (buf1, buf3, 4)" " = 0"
|
||||||
|
|
||||||
|
gdb_test {p $_regex (str1, "Hello")} " = 1"
|
||||||
|
gdb_test {p $_regex (str1, "Help")} " = 0"
|
||||||
|
gdb_test {p $_regex (str1, "^Hello")} " = 1"
|
||||||
|
gdb_test {p $_regex (str1, "^Hello.$")} " = 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_all_strfns
|
||||||
|
|
||||||
|
# Verify use in a conditional breakpoint.
|
||||||
|
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Break func here."]
|
||||||
|
gdb_test_no_output "condition \$bpnum \$_streq (arg, \"Goodbye.\")"
|
||||||
|
gdb_continue_to_breakpoint "Break func here."
|
||||||
|
gdb_test "p arg" "= $hex <str3> \"Goodbye.\""
|
||||||
|
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Break bfunc here."]
|
||||||
|
gdb_test_no_output "condition \$bpnum \$_memeq (arg, buf3, 4)"
|
||||||
|
gdb_continue_to_breakpoint "Break bfunc here."
|
||||||
|
gdb_test "p /d {char\[4\]} arg" "= \\{0, 1, 2, 4\\}"
|
||||||
|
|
||||||
|
# Verify use on a core file.
|
||||||
|
|
||||||
|
proc test_strfns_core_file { } {
|
||||||
|
global objdir subdir gdb_prompt testfile
|
||||||
|
|
||||||
|
set filename "${objdir}/${subdir}/py-strfns.core"
|
||||||
|
set escapedfilename [string_to_regexp $filename]
|
||||||
|
|
||||||
|
gdb_test_multiple "gcore $filename" \
|
||||||
|
"save a corefile" \
|
||||||
|
{
|
||||||
|
-re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
|
||||||
|
pass "save a corefile"
|
||||||
|
}
|
||||||
|
-re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
|
||||||
|
unsupported "save a corefile"
|
||||||
|
# No use proceeding from here.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_restart $testfile
|
||||||
|
|
||||||
|
gdb_test_multiple "core $filename" \
|
||||||
|
"re-load generated corefile" \
|
||||||
|
{
|
||||||
|
-re "Core was generated by .*$gdb_prompt $" {
|
||||||
|
pass "re-load generated corefile"
|
||||||
|
}
|
||||||
|
-re ".*$gdb_prompt $" {
|
||||||
|
fail "re-load generated corefile"
|
||||||
|
# No use proceeding from here.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_all_strfns
|
||||||
|
}
|
||||||
|
|
||||||
|
test_strfns_core_file
|
|
@ -114,12 +114,27 @@ proc test_fields {lang} {
|
||||||
gdb_test "python print len(fields)" "1" "Check the number of fields"
|
gdb_test "python print len(fields)" "1" "Check the number of fields"
|
||||||
gdb_test "python print fields\[0\].type" "<range type>" "Check array field type"
|
gdb_test "python print fields\[0\].type" "<range type>" "Check array field type"
|
||||||
|
|
||||||
|
# Test gdb.Type.array.
|
||||||
gdb_test "python print ar\[0\].cast(ar\[0\].type.array(1))" \
|
gdb_test "python print ar\[0\].cast(ar\[0\].type.array(1))" \
|
||||||
".1, 2." "cast to array with one argument"
|
".1, 2." "cast to array with one argument"
|
||||||
gdb_test "python print ar\[0\].cast(ar\[0\].type.array(0, 1))" \
|
gdb_test "python print ar\[0\].cast(ar\[0\].type.array(0, 1))" \
|
||||||
".1, 2." "cast to array with two arguments"
|
".1, 2." "cast to array with two arguments"
|
||||||
|
|
||||||
gdb_test "python print ar\[0\].type == ar\[0\].type" "True"
|
gdb_test "python print ar\[0\].type == ar\[0\].type" "True"
|
||||||
|
|
||||||
|
# Test gdb.Type.vector.
|
||||||
|
# Note: vectors cast differently than arrays. Here ar[0] is replicated
|
||||||
|
# for the size of the vector.
|
||||||
|
gdb_py_test_silent_cmd \
|
||||||
|
"python vec1 = ar\[0\].cast(ar\[0\].type.vector(1))" "set vec1" 1
|
||||||
|
gdb_test "python print vec1" ".1, 1." "cast to vector with one argument"
|
||||||
|
gdb_py_test_silent_cmd \
|
||||||
|
"python vec2 = ar\[0\].cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
|
||||||
|
gdb_test "python print vec2" ".1, 1." "cast to vector with two arguments"
|
||||||
|
gdb_test "python print vec1 == vec2" "True"
|
||||||
|
gdb_py_test_silent_cmd \
|
||||||
|
"python vec3 = ar\[1\].cast(ar\[1\].type.vector(1))" "set vec3" 1
|
||||||
|
gdb_test "python print vec1 == vec3" "False"
|
||||||
}
|
}
|
||||||
|
|
||||||
proc test_enums {} {
|
proc test_enums {} {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue