Tom Tromey
2011-02-11 17:21:13 UTC
Hi Phil. I want to push this to your python-breakpoints branch.
Let me know what you think.
This adds a new log-printf command that works like a printf at a certain
location, not interfering with next'ing.
I had to modify py-breakpoint.c to allow subclassing to work properly.
Without this change, a subclass couldn't allow different arguments to
__init__.
Tom
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
index 565a837..c5ef785 100644
--- a/gdb/data-directory/Makefile.in
+++ b/gdb/data-directory/Makefile.in
@@ -55,6 +55,7 @@ PYTHON_FILES = \
gdb/types.py \
gdb/printing.py \
gdb/command/__init__.py \
+ gdb/command/log.py \
gdb/command/pretty_printers.py
FLAGS_TO_PASS = \
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index 43975c2..35d4dfc 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -14,5 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import gdb.command.pretty_printers
+import gdb.command.log
gdb.command.pretty_printers.register_pretty_printer_commands()
diff --git a/gdb/python/lib/gdb/command/log.py b/gdb/python/lib/gdb/command/log.py
new file mode 100644
index 0000000..3680273
--- /dev/null
+++ b/gdb/python/lib/gdb/command/log.py
@@ -0,0 +1,57 @@
+# log-printf command
+# Copyright (C) 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/>.
+
+import gdb
+
+class _Logbp(gdb.Breakpoint):
+ "A breakpoint that logs using printf."
+
+ def __init__(self, loc, arg):
+ super(_Logbp, self).__init__(loc)
+ self._cmd = 'printf ' + arg
+
+ def eval(self):
+ gdb.execute(self._cmd, from_tty = False)
+ return False
+
+class _Logprintf(gdb.Command):
+ """A variant of printf that logs expressions at a given source location.
+
+Usage: log-printf LINESPEC -- PRINTF-ARGS
+
+LINESPEC is any linespec of the forms accepted by `break'.
+A plain `--' separates the linespec from the remaining arguments,
+which are of the form accepted by the `printf' command.
+
+This command installs a special breakpoint to do its work.
+You can disable the effects of this command by disabling or deleting
+that breakpoint."""
+
+ def __init__(self):
+ super(_Logprintf, self).__init__('log-printf',
+ gdb.COMMAND_BREAKPOINTS,
+ # Arguable.
+ gdb.COMPLETE_SYMBOL)
+
+ def invoke(self, arg, from_tty):
+ dashes = arg.find(' -- ')
+ if dashes == -1:
+ raise gdb.GdbError("could not find ` -- '")
+ linespec = arg[0 : dashes]
+ format = arg[(dashes + 4):]
+ _Logbp(linespec, format)
+
+_Logprintf()
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index f0c4ad0..8cab42f 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -577,10 +577,9 @@ bppy_get_ignore_count (PyObject *self, void *closure)
}
/* Python function to create a new breakpoint. */
-static PyObject *
-bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
+static int
+bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
- PyObject *result;
static char *keywords[] = { "spec", "type", "wp_class", "internal", NULL };
char *spec;
int type = bp_breakpoint;
@@ -591,19 +590,16 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiO", keywords,
&spec, &type, &access_type, &internal))
- return NULL;
+ return -1;
if (internal)
{
internal_bp = PyObject_IsTrue (internal);
if (internal_bp == -1)
- return NULL;
+ return -1;
}
- result = subtype->tp_alloc (subtype, 0);
- if (! result)
- return NULL;
- bppy_pending_object = (breakpoint_object *) result;
+ bppy_pending_object = (breakpoint_object *) self;
bppy_pending_object->number = -1;
bppy_pending_object->bp = NULL;
@@ -640,14 +636,14 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
}
if (except.reason < 0)
{
- subtype->tp_free (result);
- return PyErr_Format (except.reason == RETURN_QUIT
- ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
- "%s", except.message);
+ PyErr_Format (except.reason == RETURN_QUIT
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+ "%s", except.message);
+ return -1;
}
- BPPY_REQUIRE_VALID ((breakpoint_object *) result);
- return result;
+ BPPY_SET_REQUIRE_VALID ((breakpoint_object *) self);
+ return 0;
}
@@ -825,7 +821,6 @@ gdbpy_initialize_breakpoints (void)
{
int i;
- breakpoint_object_type.tp_new = bppy_new;
if (PyType_Ready (&breakpoint_object_type) < 0)
return;
@@ -941,5 +936,13 @@ static PyTypeObject breakpoint_object_type =
0, /* tp_iternext */
breakpoint_object_methods, /* tp_methods */
0, /* tp_members */
- breakpoint_object_getset /* tp_getset */
+ breakpoint_object_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ bppy_init, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew /* tp_new */
};
Let me know what you think.
This adds a new log-printf command that works like a printf at a certain
location, not interfering with next'ing.
I had to modify py-breakpoint.c to allow subclassing to work properly.
Without this change, a subclass couldn't allow different arguments to
__init__.
Tom
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
index 565a837..c5ef785 100644
--- a/gdb/data-directory/Makefile.in
+++ b/gdb/data-directory/Makefile.in
@@ -55,6 +55,7 @@ PYTHON_FILES = \
gdb/types.py \
gdb/printing.py \
gdb/command/__init__.py \
+ gdb/command/log.py \
gdb/command/pretty_printers.py
FLAGS_TO_PASS = \
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index 43975c2..35d4dfc 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -14,5 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import gdb.command.pretty_printers
+import gdb.command.log
gdb.command.pretty_printers.register_pretty_printer_commands()
diff --git a/gdb/python/lib/gdb/command/log.py b/gdb/python/lib/gdb/command/log.py
new file mode 100644
index 0000000..3680273
--- /dev/null
+++ b/gdb/python/lib/gdb/command/log.py
@@ -0,0 +1,57 @@
+# log-printf command
+# Copyright (C) 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/>.
+
+import gdb
+
+class _Logbp(gdb.Breakpoint):
+ "A breakpoint that logs using printf."
+
+ def __init__(self, loc, arg):
+ super(_Logbp, self).__init__(loc)
+ self._cmd = 'printf ' + arg
+
+ def eval(self):
+ gdb.execute(self._cmd, from_tty = False)
+ return False
+
+class _Logprintf(gdb.Command):
+ """A variant of printf that logs expressions at a given source location.
+
+Usage: log-printf LINESPEC -- PRINTF-ARGS
+
+LINESPEC is any linespec of the forms accepted by `break'.
+A plain `--' separates the linespec from the remaining arguments,
+which are of the form accepted by the `printf' command.
+
+This command installs a special breakpoint to do its work.
+You can disable the effects of this command by disabling or deleting
+that breakpoint."""
+
+ def __init__(self):
+ super(_Logprintf, self).__init__('log-printf',
+ gdb.COMMAND_BREAKPOINTS,
+ # Arguable.
+ gdb.COMPLETE_SYMBOL)
+
+ def invoke(self, arg, from_tty):
+ dashes = arg.find(' -- ')
+ if dashes == -1:
+ raise gdb.GdbError("could not find ` -- '")
+ linespec = arg[0 : dashes]
+ format = arg[(dashes + 4):]
+ _Logbp(linespec, format)
+
+_Logprintf()
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index f0c4ad0..8cab42f 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -577,10 +577,9 @@ bppy_get_ignore_count (PyObject *self, void *closure)
}
/* Python function to create a new breakpoint. */
-static PyObject *
-bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
+static int
+bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
- PyObject *result;
static char *keywords[] = { "spec", "type", "wp_class", "internal", NULL };
char *spec;
int type = bp_breakpoint;
@@ -591,19 +590,16 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiO", keywords,
&spec, &type, &access_type, &internal))
- return NULL;
+ return -1;
if (internal)
{
internal_bp = PyObject_IsTrue (internal);
if (internal_bp == -1)
- return NULL;
+ return -1;
}
- result = subtype->tp_alloc (subtype, 0);
- if (! result)
- return NULL;
- bppy_pending_object = (breakpoint_object *) result;
+ bppy_pending_object = (breakpoint_object *) self;
bppy_pending_object->number = -1;
bppy_pending_object->bp = NULL;
@@ -640,14 +636,14 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
}
if (except.reason < 0)
{
- subtype->tp_free (result);
- return PyErr_Format (except.reason == RETURN_QUIT
- ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
- "%s", except.message);
+ PyErr_Format (except.reason == RETURN_QUIT
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+ "%s", except.message);
+ return -1;
}
- BPPY_REQUIRE_VALID ((breakpoint_object *) result);
- return result;
+ BPPY_SET_REQUIRE_VALID ((breakpoint_object *) self);
+ return 0;
}
@@ -825,7 +821,6 @@ gdbpy_initialize_breakpoints (void)
{
int i;
- breakpoint_object_type.tp_new = bppy_new;
if (PyType_Ready (&breakpoint_object_type) < 0)
return;
@@ -941,5 +936,13 @@ static PyTypeObject breakpoint_object_type =
0, /* tp_iternext */
breakpoint_object_methods, /* tp_methods */
0, /* tp_members */
- breakpoint_object_getset /* tp_getset */
+ breakpoint_object_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ bppy_init, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew /* tp_new */
};