2013-11-11 20:49:45 +01:00
|
|
|
|
/* Python interface to line tables.
|
|
|
|
|
|
2017-01-01 07:50:51 +01:00
|
|
|
|
Copyright (C) 2013-2017 Free Software Foundation, Inc.
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
This file is part of GDB.
|
|
|
|
|
|
|
|
|
|
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 "defs.h"
|
|
|
|
|
#include "python-internal.h"
|
2016-11-07 05:25:34 +01:00
|
|
|
|
#include "py-ref.h"
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
PyObject_HEAD
|
|
|
|
|
/* The line table source line. */
|
|
|
|
|
int line;
|
|
|
|
|
/* The pc associated with the source line. */
|
|
|
|
|
CORE_ADDR pc;
|
|
|
|
|
} linetable_entry_object;
|
|
|
|
|
|
Fix redefinition errors in C++ mode
In C, we can forward declare static structure instances. That doesn't
work in C++ though. C++ treats these as definitions. So then the
compiler complains about symbol redefinition, like:
src/gdb/elfread.c:1569:29: error: redefinition of ‘const sym_fns elf_sym_fns_lazy_psyms’
src/gdb/elfread.c:53:29: error: ‘const sym_fns elf_sym_fns_lazy_psyms’ previously declared here
The intent of static here is naturally to avoid making these objects
visible outside the compilation unit. The equivalent in C++ would be
to instead define the objects in the anonymous namespace. But given
that it's desirable to leave the codebase compiling as both C and C++
for a while, this just makes the objects extern.
(base_breakpoint_ops is already declared in breakpoint.h, so we can
just remove the forward declare from breakpoint.c)
gdb/ChangeLog:
2015-02-11 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
* breakpoint.c (base_breakpoint_ops): Delete.
* dwarf2loc.c (dwarf_expr_ctx_funcs): Make extern.
* elfread.c (elf_sym_fns_gdb_index, elf_sym_fns_lazy_psyms): Make extern.
* guile/guile.c (guile_extension_script_ops, guile_extension_ops): Make extern.
* ppcnbsd-tdep.c (ppcnbsd2_sigtramp): Make extern.
* python/py-arch.c (arch_object_type): Make extern.
* python/py-block.c (block_syms_iterator_object_type): Make extern.
* python/py-bpevent.c (breakpoint_event_object_type): Make extern.
* python/py-cmd.c (cmdpy_object_type): Make extern.
* python/py-continueevent.c (continue_event_object_type)
* python/py-event.h (GDBPY_NEW_EVENT_TYPE): Remove 'qual'
parameter. Update all callers.
* python/py-evtregistry.c (eventregistry_object_type): Make extern.
* python/py-exitedevent.c (exited_event_object_type): Make extern.
* python/py-finishbreakpoint.c (finish_breakpoint_object_type): Make extern.
* python/py-function.c (fnpy_object_type): Make extern.
* python/py-inferior.c (inferior_object_type, membuf_object_type): Make extern.
* python/py-infevents.c (call_pre_event_object_type)
(inferior_call_post_event_object_type).
(memory_changed_event_object_type): Make extern.
* python/py-infthread.c (thread_object_type): Make extern.
* python/py-lazy-string.c (lazy_string_object_type): Make extern.
* python/py-linetable.c (linetable_entry_object_type)
(linetable_object_type, ltpy_iterator_object_type): Make extern.
* python/py-newobjfileevent.c (new_objfile_event_object_type)
(clear_objfiles_event_object_type): Make extern.
* python/py-objfile.c (objfile_object_type): Make extern.
* python/py-param.c (parmpy_object_type): Make extern.
* python/py-progspace.c (pspace_object_type): Make extern.
* python/py-signalevent.c (signal_event_object_type): Make extern.
* python/py-symtab.c (symtab_object_type, sal_object_type): Make extern.
* python/py-type.c (type_object_type, field_object_type)
(type_iterator_object_type): Make extern.
* python/python.c (python_extension_script_ops)
(python_extension_ops): Make extern.
* stap-probe.c (stap_probe_ops): Make extern.
2015-02-11 12:20:21 +01:00
|
|
|
|
extern PyTypeObject linetable_entry_object_type
|
2013-11-11 20:49:45 +01:00
|
|
|
|
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_entry_object");
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
PyObject_HEAD
|
|
|
|
|
/* The symtab python object. We store the Python object here as the
|
|
|
|
|
underlying symtab can become invalid, and we have to run validity
|
|
|
|
|
checks on it. */
|
|
|
|
|
PyObject *symtab;
|
|
|
|
|
} linetable_object;
|
|
|
|
|
|
Fix redefinition errors in C++ mode
In C, we can forward declare static structure instances. That doesn't
work in C++ though. C++ treats these as definitions. So then the
compiler complains about symbol redefinition, like:
src/gdb/elfread.c:1569:29: error: redefinition of ‘const sym_fns elf_sym_fns_lazy_psyms’
src/gdb/elfread.c:53:29: error: ‘const sym_fns elf_sym_fns_lazy_psyms’ previously declared here
The intent of static here is naturally to avoid making these objects
visible outside the compilation unit. The equivalent in C++ would be
to instead define the objects in the anonymous namespace. But given
that it's desirable to leave the codebase compiling as both C and C++
for a while, this just makes the objects extern.
(base_breakpoint_ops is already declared in breakpoint.h, so we can
just remove the forward declare from breakpoint.c)
gdb/ChangeLog:
2015-02-11 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
* breakpoint.c (base_breakpoint_ops): Delete.
* dwarf2loc.c (dwarf_expr_ctx_funcs): Make extern.
* elfread.c (elf_sym_fns_gdb_index, elf_sym_fns_lazy_psyms): Make extern.
* guile/guile.c (guile_extension_script_ops, guile_extension_ops): Make extern.
* ppcnbsd-tdep.c (ppcnbsd2_sigtramp): Make extern.
* python/py-arch.c (arch_object_type): Make extern.
* python/py-block.c (block_syms_iterator_object_type): Make extern.
* python/py-bpevent.c (breakpoint_event_object_type): Make extern.
* python/py-cmd.c (cmdpy_object_type): Make extern.
* python/py-continueevent.c (continue_event_object_type)
* python/py-event.h (GDBPY_NEW_EVENT_TYPE): Remove 'qual'
parameter. Update all callers.
* python/py-evtregistry.c (eventregistry_object_type): Make extern.
* python/py-exitedevent.c (exited_event_object_type): Make extern.
* python/py-finishbreakpoint.c (finish_breakpoint_object_type): Make extern.
* python/py-function.c (fnpy_object_type): Make extern.
* python/py-inferior.c (inferior_object_type, membuf_object_type): Make extern.
* python/py-infevents.c (call_pre_event_object_type)
(inferior_call_post_event_object_type).
(memory_changed_event_object_type): Make extern.
* python/py-infthread.c (thread_object_type): Make extern.
* python/py-lazy-string.c (lazy_string_object_type): Make extern.
* python/py-linetable.c (linetable_entry_object_type)
(linetable_object_type, ltpy_iterator_object_type): Make extern.
* python/py-newobjfileevent.c (new_objfile_event_object_type)
(clear_objfiles_event_object_type): Make extern.
* python/py-objfile.c (objfile_object_type): Make extern.
* python/py-param.c (parmpy_object_type): Make extern.
* python/py-progspace.c (pspace_object_type): Make extern.
* python/py-signalevent.c (signal_event_object_type): Make extern.
* python/py-symtab.c (symtab_object_type, sal_object_type): Make extern.
* python/py-type.c (type_object_type, field_object_type)
(type_iterator_object_type): Make extern.
* python/python.c (python_extension_script_ops)
(python_extension_ops): Make extern.
* stap-probe.c (stap_probe_ops): Make extern.
2015-02-11 12:20:21 +01:00
|
|
|
|
extern PyTypeObject linetable_object_type
|
2013-11-11 20:49:45 +01:00
|
|
|
|
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_object");
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
PyObject_HEAD
|
|
|
|
|
/* The current entry in the line table for the iterator */
|
|
|
|
|
int current_index;
|
|
|
|
|
/* Pointer back to the original source line table object. Needed to
|
|
|
|
|
check if the line table is still valid, and has not been invalidated
|
|
|
|
|
when an object file has been freed. */
|
|
|
|
|
PyObject *source;
|
|
|
|
|
} ltpy_iterator_object;
|
|
|
|
|
|
Fix redefinition errors in C++ mode
In C, we can forward declare static structure instances. That doesn't
work in C++ though. C++ treats these as definitions. So then the
compiler complains about symbol redefinition, like:
src/gdb/elfread.c:1569:29: error: redefinition of ‘const sym_fns elf_sym_fns_lazy_psyms’
src/gdb/elfread.c:53:29: error: ‘const sym_fns elf_sym_fns_lazy_psyms’ previously declared here
The intent of static here is naturally to avoid making these objects
visible outside the compilation unit. The equivalent in C++ would be
to instead define the objects in the anonymous namespace. But given
that it's desirable to leave the codebase compiling as both C and C++
for a while, this just makes the objects extern.
(base_breakpoint_ops is already declared in breakpoint.h, so we can
just remove the forward declare from breakpoint.c)
gdb/ChangeLog:
2015-02-11 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
* breakpoint.c (base_breakpoint_ops): Delete.
* dwarf2loc.c (dwarf_expr_ctx_funcs): Make extern.
* elfread.c (elf_sym_fns_gdb_index, elf_sym_fns_lazy_psyms): Make extern.
* guile/guile.c (guile_extension_script_ops, guile_extension_ops): Make extern.
* ppcnbsd-tdep.c (ppcnbsd2_sigtramp): Make extern.
* python/py-arch.c (arch_object_type): Make extern.
* python/py-block.c (block_syms_iterator_object_type): Make extern.
* python/py-bpevent.c (breakpoint_event_object_type): Make extern.
* python/py-cmd.c (cmdpy_object_type): Make extern.
* python/py-continueevent.c (continue_event_object_type)
* python/py-event.h (GDBPY_NEW_EVENT_TYPE): Remove 'qual'
parameter. Update all callers.
* python/py-evtregistry.c (eventregistry_object_type): Make extern.
* python/py-exitedevent.c (exited_event_object_type): Make extern.
* python/py-finishbreakpoint.c (finish_breakpoint_object_type): Make extern.
* python/py-function.c (fnpy_object_type): Make extern.
* python/py-inferior.c (inferior_object_type, membuf_object_type): Make extern.
* python/py-infevents.c (call_pre_event_object_type)
(inferior_call_post_event_object_type).
(memory_changed_event_object_type): Make extern.
* python/py-infthread.c (thread_object_type): Make extern.
* python/py-lazy-string.c (lazy_string_object_type): Make extern.
* python/py-linetable.c (linetable_entry_object_type)
(linetable_object_type, ltpy_iterator_object_type): Make extern.
* python/py-newobjfileevent.c (new_objfile_event_object_type)
(clear_objfiles_event_object_type): Make extern.
* python/py-objfile.c (objfile_object_type): Make extern.
* python/py-param.c (parmpy_object_type): Make extern.
* python/py-progspace.c (pspace_object_type): Make extern.
* python/py-signalevent.c (signal_event_object_type): Make extern.
* python/py-symtab.c (symtab_object_type, sal_object_type): Make extern.
* python/py-type.c (type_object_type, field_object_type)
(type_iterator_object_type): Make extern.
* python/python.c (python_extension_script_ops)
(python_extension_ops): Make extern.
* stap-probe.c (stap_probe_ops): Make extern.
2015-02-11 12:20:21 +01:00
|
|
|
|
extern PyTypeObject ltpy_iterator_object_type
|
2013-11-11 20:49:45 +01:00
|
|
|
|
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("ltpy_iterator_object");
|
|
|
|
|
|
2015-08-04 18:03:15 +02:00
|
|
|
|
/* Internal helper function to extract gdb.Symtab from a gdb.LineTable
|
2013-11-11 20:49:45 +01:00
|
|
|
|
object. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
get_symtab (PyObject *linetable)
|
|
|
|
|
{
|
|
|
|
|
linetable_object *lt = (linetable_object *) linetable;
|
|
|
|
|
|
|
|
|
|
return lt->symtab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define LTPY_REQUIRE_VALID(lt_obj, symtab) \
|
|
|
|
|
do { \
|
|
|
|
|
symtab = symtab_object_to_symtab (get_symtab (lt_obj)); \
|
|
|
|
|
if (symtab == NULL) \
|
|
|
|
|
{ \
|
|
|
|
|
PyErr_SetString (PyExc_RuntimeError, \
|
|
|
|
|
_("Symbol Table in line table is invalid."));\
|
|
|
|
|
return NULL; \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Helper function to create a line table object that wraps a
|
|
|
|
|
gdb.Symtab object. */
|
|
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
|
symtab_to_linetable_object (PyObject *symtab)
|
|
|
|
|
{
|
|
|
|
|
linetable_object *ltable;
|
|
|
|
|
|
|
|
|
|
ltable = PyObject_New (linetable_object, &linetable_object_type);
|
|
|
|
|
if (ltable != NULL)
|
|
|
|
|
{
|
|
|
|
|
ltable->symtab = symtab;
|
|
|
|
|
Py_INCREF (symtab);
|
|
|
|
|
}
|
|
|
|
|
return (PyObject *) ltable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Internal helper function to build a line table object from a line
|
|
|
|
|
and an address. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
build_linetable_entry (int line, CORE_ADDR address)
|
|
|
|
|
{
|
|
|
|
|
linetable_entry_object *obj;
|
|
|
|
|
|
|
|
|
|
obj = PyObject_New (linetable_entry_object,
|
|
|
|
|
&linetable_entry_object_type);
|
|
|
|
|
if (obj != NULL)
|
|
|
|
|
{
|
|
|
|
|
obj->line = line;
|
|
|
|
|
obj->pc = address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (PyObject *) obj;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-07 00:38:56 +02:00
|
|
|
|
/* Internal helper function to build a Python Tuple from a vector.
|
2013-11-11 20:49:45 +01:00
|
|
|
|
A line table entry can have multiple PCs for a given source line.
|
|
|
|
|
Construct a Tuple of all entries for the given source line, LINE
|
2017-04-07 00:38:56 +02:00
|
|
|
|
from the line table PCS. Construct one line table entry object per
|
2013-11-11 20:49:45 +01:00
|
|
|
|
address. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
2017-04-07 00:38:56 +02:00
|
|
|
|
build_line_table_tuple_from_pcs (int line, const std::vector<CORE_ADDR> &pcs)
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
2017-04-07 00:38:56 +02:00
|
|
|
|
if (pcs.size () < 1)
|
2013-11-11 20:49:45 +01:00
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
|
2017-04-07 00:38:56 +02:00
|
|
|
|
gdbpy_ref<> tuple (PyTuple_New (pcs.size ()));
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
if (tuple == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2017-04-07 00:38:56 +02:00
|
|
|
|
for (i = 0; i < pcs.size (); ++i)
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{
|
2017-04-07 00:38:56 +02:00
|
|
|
|
CORE_ADDR pc = pcs[i];
|
Turn gdbpy_ref into a template
This turns gdbpy_ref into a template class, so that it can be used to
wrap subclasses of PyObject. The default argument remains PyObject;
and this necessitated renaming uses of "gdbpy_ref" to "gdbpy_ref<>".
gdb/ChangeLog
2017-02-10 Tom Tromey <tom@tromey.com>
* python/py-ref.h (gdbpy_ref_policy): Now a template.
(gdbpy_ref): Now a template; allow subclasses of PyObject to be
used.
* python/py-arch.c, python/py-bpevent.c, python/py-breakpoint.c,
python/py-cmd.c, python/py-continueevent.c, python/py-event.c,
python/py-exitedevent.c, python/py-finishbreakpoint.c,
python/py-framefilter.c, python/py-function.c,
python/py-inferior.c, python/py-infevents.c,
python/py-linetable.c, python/py-newobjfileevent.c,
python/py-param.c, python/py-prettyprint.c, python/py-ref.h,
python/py-signalevent.c, python/py-stopevent.c,
python/py-symbol.c, python/py-threadevent.c, python/py-type.c,
python/py-unwind.c, python/py-utils.c, python/py-value.c,
python/py-varobj.c, python/py-xmethods.c, python/python.c,
varobj.c: Change gdbpy_ref to gdbpy_ref<>.
2017-02-09 21:16:36 +01:00
|
|
|
|
gdbpy_ref<> obj (build_linetable_entry (line, pc));
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
if (obj == NULL)
|
2016-11-07 05:25:34 +01:00
|
|
|
|
return NULL;
|
|
|
|
|
else if (PyTuple_SetItem (tuple.get (), i, obj.release ()) != 0)
|
|
|
|
|
return NULL;
|
2013-11-11 20:49:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
2016-11-07 05:25:34 +01:00
|
|
|
|
return tuple.release ();
|
2013-11-11 20:49:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Implementation of gdb.LineTable.line (self) -> Tuple. Returns a
|
|
|
|
|
tuple of LineTableEntry objects associated with this line from the
|
|
|
|
|
in the line table. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
|
|
|
|
|
{
|
|
|
|
|
struct symtab *symtab;
|
2014-02-09 18:47:40 +01:00
|
|
|
|
gdb_py_longest py_line;
|
2013-11-11 20:49:45 +01:00
|
|
|
|
struct linetable_entry *best_entry = NULL;
|
2017-04-07 00:38:56 +02:00
|
|
|
|
std::vector<CORE_ADDR> pcs;
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
LTPY_REQUIRE_VALID (self, symtab);
|
|
|
|
|
|
|
|
|
|
if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
Split TRY_CATCH into TRY + CATCH
This patch splits the TRY_CATCH macro into three, so that we go from
this:
~~~
volatile gdb_exception ex;
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
}
if (ex.reason < 0)
{
}
~~~
to this:
~~~
TRY
{
}
CATCH (ex, RETURN_MASK_ERROR)
{
}
END_CATCH
~~~
Thus, we'll be getting rid of the local volatile exception object, and
declaring the caught exception in the catch block.
This allows reimplementing TRY/CATCH in terms of C++ exceptions when
building in C++ mode, while still allowing to build GDB in C mode
(using setjmp/longjmp), as a transition step.
TBC, after this patch, is it _not_ valid to have code between the TRY
and the CATCH blocks, like:
TRY
{
}
// some code here.
CATCH (ex, RETURN_MASK_ERROR)
{
}
END_CATCH
Just like it isn't valid to do that with C++'s native try/catch.
By switching to creating the exception object inside the CATCH block
scope, we can get rid of all the explicitly allocated volatile
exception objects all over the tree, and map the CATCH block more
directly to C++'s catch blocks.
The majority of the TRY_CATCH -> TRY+CATCH+END_CATCH conversion was
done with a script, rerun from scratch at every rebase, no manual
editing involved. After the mechanical conversion, a few places
needed manual intervention, to fix preexisting cases where we were
using the exception object outside of the TRY_CATCH block, and cases
where we were using "else" after a 'if (ex.reason) < 0)' [a CATCH
after this patch]. The result was folded into this patch so that GDB
still builds at each incremental step.
END_CATCH is necessary for two reasons:
First, because we name the exception object in the CATCH block, which
requires creating a scope, which in turn must be closed somewhere.
Declaring the exception variable in the initializer field of a for
block, like:
#define CATCH(EXCEPTION, mask) \
for (struct gdb_exception EXCEPTION; \
exceptions_state_mc_catch (&EXCEPTION, MASK); \
EXCEPTION = exception_none)
would avoid needing END_CATCH, but alas, in C mode, we build with C90,
which doesn't allow mixed declarations and code.
Second, because when TRY/CATCH are wired to real C++ try/catch, as
long as we need to handle cleanup chains, even if there's no CATCH
block that wants to catch the exception, we need for stop at every
frame in the unwind chain and run cleanups, then rethrow. That will
be done in END_CATCH.
After we require C++, we'll still need TRY/CATCH/END_CATCH until
cleanups are completely phased out -- TRY/CATCH in C++ mode will
save/restore the current cleanup chain, like in C mode, and END_CATCH
catches otherwise uncaugh exceptions, runs cleanups and rethrows, so
that C++ cleanups and exceptions can coexist.
IMO, this still makes the TRY/CATCH code look a bit more like a
newcomer would expect, so IMO worth it even if we weren't considering
C++.
gdb/ChangeLog.
2015-03-07 Pedro Alves <palves@redhat.com>
* common/common-exceptions.c (struct catcher) <exception>: No
longer a pointer to volatile exception. Now an exception value.
<mask>: Delete field.
(exceptions_state_mc_init): Remove all parameters. Adjust.
(exceptions_state_mc): No longer pop the catcher here.
(exceptions_state_mc_catch): New function.
(throw_exception): Adjust.
* common/common-exceptions.h (exceptions_state_mc_init): Remove
all parameters.
(exceptions_state_mc_catch): Declare.
(TRY_CATCH): Rename to ...
(TRY): ... this. Remove EXCEPTION and MASK parameters.
(CATCH, END_CATCH): New.
All callers adjusted.
gdb/gdbserver/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
Adjust all callers of TRY_CATCH to use TRY/CATCH/END_CATCH
instead.
2015-03-07 16:14:14 +01:00
|
|
|
|
TRY
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{
|
|
|
|
|
pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry);
|
|
|
|
|
}
|
Split TRY_CATCH into TRY + CATCH
This patch splits the TRY_CATCH macro into three, so that we go from
this:
~~~
volatile gdb_exception ex;
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
}
if (ex.reason < 0)
{
}
~~~
to this:
~~~
TRY
{
}
CATCH (ex, RETURN_MASK_ERROR)
{
}
END_CATCH
~~~
Thus, we'll be getting rid of the local volatile exception object, and
declaring the caught exception in the catch block.
This allows reimplementing TRY/CATCH in terms of C++ exceptions when
building in C++ mode, while still allowing to build GDB in C mode
(using setjmp/longjmp), as a transition step.
TBC, after this patch, is it _not_ valid to have code between the TRY
and the CATCH blocks, like:
TRY
{
}
// some code here.
CATCH (ex, RETURN_MASK_ERROR)
{
}
END_CATCH
Just like it isn't valid to do that with C++'s native try/catch.
By switching to creating the exception object inside the CATCH block
scope, we can get rid of all the explicitly allocated volatile
exception objects all over the tree, and map the CATCH block more
directly to C++'s catch blocks.
The majority of the TRY_CATCH -> TRY+CATCH+END_CATCH conversion was
done with a script, rerun from scratch at every rebase, no manual
editing involved. After the mechanical conversion, a few places
needed manual intervention, to fix preexisting cases where we were
using the exception object outside of the TRY_CATCH block, and cases
where we were using "else" after a 'if (ex.reason) < 0)' [a CATCH
after this patch]. The result was folded into this patch so that GDB
still builds at each incremental step.
END_CATCH is necessary for two reasons:
First, because we name the exception object in the CATCH block, which
requires creating a scope, which in turn must be closed somewhere.
Declaring the exception variable in the initializer field of a for
block, like:
#define CATCH(EXCEPTION, mask) \
for (struct gdb_exception EXCEPTION; \
exceptions_state_mc_catch (&EXCEPTION, MASK); \
EXCEPTION = exception_none)
would avoid needing END_CATCH, but alas, in C mode, we build with C90,
which doesn't allow mixed declarations and code.
Second, because when TRY/CATCH are wired to real C++ try/catch, as
long as we need to handle cleanup chains, even if there's no CATCH
block that wants to catch the exception, we need for stop at every
frame in the unwind chain and run cleanups, then rethrow. That will
be done in END_CATCH.
After we require C++, we'll still need TRY/CATCH/END_CATCH until
cleanups are completely phased out -- TRY/CATCH in C++ mode will
save/restore the current cleanup chain, like in C mode, and END_CATCH
catches otherwise uncaugh exceptions, runs cleanups and rethrows, so
that C++ cleanups and exceptions can coexist.
IMO, this still makes the TRY/CATCH code look a bit more like a
newcomer would expect, so IMO worth it even if we weren't considering
C++.
gdb/ChangeLog.
2015-03-07 Pedro Alves <palves@redhat.com>
* common/common-exceptions.c (struct catcher) <exception>: No
longer a pointer to volatile exception. Now an exception value.
<mask>: Delete field.
(exceptions_state_mc_init): Remove all parameters. Adjust.
(exceptions_state_mc): No longer pop the catcher here.
(exceptions_state_mc_catch): New function.
(throw_exception): Adjust.
* common/common-exceptions.h (exceptions_state_mc_init): Remove
all parameters.
(exceptions_state_mc_catch): Declare.
(TRY_CATCH): Rename to ...
(TRY): ... this. Remove EXCEPTION and MASK parameters.
(CATCH, END_CATCH): New.
All callers adjusted.
gdb/gdbserver/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
Adjust all callers of TRY_CATCH to use TRY/CATCH/END_CATCH
instead.
2015-03-07 16:14:14 +01:00
|
|
|
|
CATCH (except, RETURN_MASK_ALL)
|
|
|
|
|
{
|
|
|
|
|
GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
|
|
}
|
|
|
|
|
END_CATCH
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
2017-04-07 00:38:56 +02:00
|
|
|
|
return build_line_table_tuple_from_pcs (py_line, pcs);
|
2013-11-11 20:49:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
|
|
|
|
|
Returns a Python Boolean indicating whether a source line has any
|
|
|
|
|
line table entries corresponding to it. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_has_line (PyObject *self, PyObject *args)
|
|
|
|
|
{
|
|
|
|
|
struct symtab *symtab;
|
2014-02-09 18:47:40 +01:00
|
|
|
|
gdb_py_longest py_line;
|
2013-11-11 20:49:45 +01:00
|
|
|
|
int index;
|
|
|
|
|
|
|
|
|
|
LTPY_REQUIRE_VALID (self, symtab);
|
|
|
|
|
|
|
|
|
|
if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2014-11-18 18:32:10 +01:00
|
|
|
|
if (SYMTAB_LINETABLE (symtab) == NULL)
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{
|
|
|
|
|
PyErr_SetString (PyExc_RuntimeError,
|
|
|
|
|
_("Linetable information not found in symbol table"));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-18 18:32:10 +01:00
|
|
|
|
for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{
|
2014-11-18 18:32:10 +01:00
|
|
|
|
struct linetable_entry *item = &(SYMTAB_LINETABLE (symtab)->item[index]);
|
2013-11-11 20:49:45 +01:00
|
|
|
|
if (item->line == py_line)
|
|
|
|
|
Py_RETURN_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Py_RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 15:36:25 +02:00
|
|
|
|
/* Implementation of gdb.LineTable.source_lines (self) -> List.
|
|
|
|
|
Returns a Python List that contains source line entries in the
|
2013-11-11 20:49:45 +01:00
|
|
|
|
line table. This function will just return the source lines
|
|
|
|
|
without corresponding addresses. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_get_all_source_lines (PyObject *self, PyObject *args)
|
|
|
|
|
{
|
|
|
|
|
struct symtab *symtab;
|
|
|
|
|
Py_ssize_t index;
|
|
|
|
|
struct linetable_entry *item;
|
|
|
|
|
|
|
|
|
|
LTPY_REQUIRE_VALID (self, symtab);
|
|
|
|
|
|
2014-11-18 18:32:10 +01:00
|
|
|
|
if (SYMTAB_LINETABLE (symtab) == NULL)
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{
|
|
|
|
|
PyErr_SetString (PyExc_RuntimeError,
|
|
|
|
|
_("Linetable information not found in symbol table"));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
Turn gdbpy_ref into a template
This turns gdbpy_ref into a template class, so that it can be used to
wrap subclasses of PyObject. The default argument remains PyObject;
and this necessitated renaming uses of "gdbpy_ref" to "gdbpy_ref<>".
gdb/ChangeLog
2017-02-10 Tom Tromey <tom@tromey.com>
* python/py-ref.h (gdbpy_ref_policy): Now a template.
(gdbpy_ref): Now a template; allow subclasses of PyObject to be
used.
* python/py-arch.c, python/py-bpevent.c, python/py-breakpoint.c,
python/py-cmd.c, python/py-continueevent.c, python/py-event.c,
python/py-exitedevent.c, python/py-finishbreakpoint.c,
python/py-framefilter.c, python/py-function.c,
python/py-inferior.c, python/py-infevents.c,
python/py-linetable.c, python/py-newobjfileevent.c,
python/py-param.c, python/py-prettyprint.c, python/py-ref.h,
python/py-signalevent.c, python/py-stopevent.c,
python/py-symbol.c, python/py-threadevent.c, python/py-type.c,
python/py-unwind.c, python/py-utils.c, python/py-value.c,
python/py-varobj.c, python/py-xmethods.c, python/python.c,
varobj.c: Change gdbpy_ref to gdbpy_ref<>.
2017-02-09 21:16:36 +01:00
|
|
|
|
gdbpy_ref<> source_dict (PyDict_New ());
|
2013-11-11 20:49:45 +01:00
|
|
|
|
if (source_dict == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2014-11-18 18:32:10 +01:00
|
|
|
|
for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{
|
2014-11-18 18:32:10 +01:00
|
|
|
|
item = &(SYMTAB_LINETABLE (symtab)->item[index]);
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
/* 0 is used to signify end of line table information. Do not
|
|
|
|
|
include in the source set. */
|
|
|
|
|
if (item->line > 0)
|
|
|
|
|
{
|
Turn gdbpy_ref into a template
This turns gdbpy_ref into a template class, so that it can be used to
wrap subclasses of PyObject. The default argument remains PyObject;
and this necessitated renaming uses of "gdbpy_ref" to "gdbpy_ref<>".
gdb/ChangeLog
2017-02-10 Tom Tromey <tom@tromey.com>
* python/py-ref.h (gdbpy_ref_policy): Now a template.
(gdbpy_ref): Now a template; allow subclasses of PyObject to be
used.
* python/py-arch.c, python/py-bpevent.c, python/py-breakpoint.c,
python/py-cmd.c, python/py-continueevent.c, python/py-event.c,
python/py-exitedevent.c, python/py-finishbreakpoint.c,
python/py-framefilter.c, python/py-function.c,
python/py-inferior.c, python/py-infevents.c,
python/py-linetable.c, python/py-newobjfileevent.c,
python/py-param.c, python/py-prettyprint.c, python/py-ref.h,
python/py-signalevent.c, python/py-stopevent.c,
python/py-symbol.c, python/py-threadevent.c, python/py-type.c,
python/py-unwind.c, python/py-utils.c, python/py-value.c,
python/py-varobj.c, python/py-xmethods.c, python/python.c,
varobj.c: Change gdbpy_ref to gdbpy_ref<>.
2017-02-09 21:16:36 +01:00
|
|
|
|
gdbpy_ref<> line (gdb_py_object_from_longest (item->line));
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
if (line == NULL)
|
2016-11-07 05:25:34 +01:00
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (PyDict_SetItem (source_dict.get (), line.get (), Py_None) == -1)
|
|
|
|
|
return NULL;
|
2013-11-11 20:49:45 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-07 05:25:34 +01:00
|
|
|
|
return PyDict_Keys (source_dict.get ());
|
2013-11-11 20:49:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-04 18:03:15 +02:00
|
|
|
|
/* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
|
2013-11-11 20:49:45 +01:00
|
|
|
|
Returns True if this line table object still exists in GDB. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_is_valid (PyObject *self, PyObject *args)
|
|
|
|
|
{
|
|
|
|
|
struct symtab *symtab = NULL;
|
|
|
|
|
|
|
|
|
|
symtab = symtab_object_to_symtab (get_symtab (self));
|
|
|
|
|
|
|
|
|
|
if (symtab == NULL)
|
|
|
|
|
Py_RETURN_FALSE;
|
|
|
|
|
|
|
|
|
|
Py_RETURN_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Deconstructor for the line table object. Decrement the reference
|
|
|
|
|
to the symbol table object before calling the default free. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ltpy_dealloc (PyObject *self)
|
|
|
|
|
{
|
|
|
|
|
linetable_object *obj = (linetable_object *) self;
|
|
|
|
|
|
|
|
|
|
Py_DECREF (obj->symtab);
|
|
|
|
|
Py_TYPE (self)->tp_free (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize LineTable, LineTableEntry and LineTableIterator
|
|
|
|
|
objects. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
gdbpy_initialize_linetable (void)
|
|
|
|
|
{
|
|
|
|
|
if (PyType_Ready (&linetable_object_type) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
if (PyType_Ready (&linetable_entry_object_type) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
if (PyType_Ready (<py_iterator_object_type) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
Py_INCREF (&linetable_object_type);
|
|
|
|
|
Py_INCREF (&linetable_entry_object_type);
|
|
|
|
|
Py_INCREF (<py_iterator_object_type);
|
|
|
|
|
|
|
|
|
|
if (gdb_pymodule_addobject (gdb_module, "LineTable",
|
|
|
|
|
(PyObject *) &linetable_object_type) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
if (gdb_pymodule_addobject (gdb_module, "LineTableEntry",
|
|
|
|
|
(PyObject *) &linetable_entry_object_type) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
if (gdb_pymodule_addobject (gdb_module, "LineTableIterator",
|
|
|
|
|
(PyObject *) <py_iterator_object_type) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-04 18:03:15 +02:00
|
|
|
|
/* LineTable entry object get functions. */
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
/* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
|
|
|
|
|
a long integer associated with the line table entry. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_entry_get_line (PyObject *self, void *closure)
|
|
|
|
|
{
|
|
|
|
|
linetable_entry_object *obj = (linetable_entry_object *) self;
|
|
|
|
|
|
|
|
|
|
return gdb_py_object_from_longest (obj->line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
|
|
|
|
|
a long integer associated with the PC of the line table entry. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_entry_get_pc (PyObject *self, void *closure)
|
|
|
|
|
{
|
|
|
|
|
linetable_entry_object *obj = (linetable_entry_object *) self;
|
|
|
|
|
|
|
|
|
|
return gdb_py_object_from_longest (obj->pc);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-04 18:03:15 +02:00
|
|
|
|
/* LineTable iterator functions. */
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
/* Return a new line table iterator. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_iter (PyObject *self)
|
|
|
|
|
{
|
|
|
|
|
ltpy_iterator_object *ltpy_iter_obj;
|
|
|
|
|
struct symtab *symtab = NULL;
|
|
|
|
|
|
|
|
|
|
LTPY_REQUIRE_VALID (self, symtab);
|
|
|
|
|
|
|
|
|
|
ltpy_iter_obj = PyObject_New (ltpy_iterator_object,
|
|
|
|
|
<py_iterator_object_type);
|
|
|
|
|
if (ltpy_iter_obj == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
ltpy_iter_obj->current_index = 0;
|
|
|
|
|
ltpy_iter_obj->source = self;
|
|
|
|
|
|
|
|
|
|
Py_INCREF (self);
|
|
|
|
|
return (PyObject *) ltpy_iter_obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ltpy_iterator_dealloc (PyObject *obj)
|
|
|
|
|
{
|
|
|
|
|
ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) obj;
|
|
|
|
|
|
|
|
|
|
Py_DECREF (iter_obj->source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return a reference to the line table iterator. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_iterator (PyObject *self)
|
|
|
|
|
{
|
|
|
|
|
ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
|
|
|
|
|
struct symtab *symtab;
|
|
|
|
|
|
|
|
|
|
LTPY_REQUIRE_VALID (iter_obj->source, symtab);
|
|
|
|
|
|
|
|
|
|
Py_INCREF (self);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the next line table entry in the iteration through the line
|
|
|
|
|
table data structure. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_iternext (PyObject *self)
|
|
|
|
|
{
|
|
|
|
|
ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
|
|
|
|
|
struct symtab *symtab;
|
|
|
|
|
PyObject *obj;
|
|
|
|
|
struct linetable_entry *item;
|
|
|
|
|
|
|
|
|
|
LTPY_REQUIRE_VALID (iter_obj->source, symtab);
|
|
|
|
|
|
2014-11-18 18:32:10 +01:00
|
|
|
|
if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
|
2017-01-12 16:59:26 +01:00
|
|
|
|
{
|
|
|
|
|
PyErr_SetNone (PyExc_StopIteration);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
2014-11-18 18:32:10 +01:00
|
|
|
|
item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
|
2013-11-11 20:49:45 +01:00
|
|
|
|
|
|
|
|
|
/* Skip over internal entries such as 0. 0 signifies the end of
|
|
|
|
|
line table data and is not useful to the API user. */
|
|
|
|
|
while (item->line < 1)
|
|
|
|
|
{
|
|
|
|
|
iter_obj->current_index++;
|
|
|
|
|
|
|
|
|
|
/* Exit if the internal value is the last item in the line table. */
|
2014-11-18 18:32:10 +01:00
|
|
|
|
if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
|
2017-01-12 16:59:26 +01:00
|
|
|
|
{
|
|
|
|
|
PyErr_SetNone (PyExc_StopIteration);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2014-11-18 18:32:10 +01:00
|
|
|
|
item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
|
2013-11-11 20:49:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
obj = build_linetable_entry (item->line, item->pc);
|
|
|
|
|
iter_obj->current_index++;
|
|
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-04 18:03:15 +02:00
|
|
|
|
/* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
|
2013-11-11 20:49:45 +01:00
|
|
|
|
Returns True if this line table iterator object still exists in
|
|
|
|
|
GDB. */
|
|
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
|
ltpy_iter_is_valid (PyObject *self, PyObject *args)
|
|
|
|
|
{
|
|
|
|
|
struct symtab *symtab = NULL;
|
|
|
|
|
ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
|
|
|
|
|
|
|
|
|
|
symtab = symtab_object_to_symtab (get_symtab (iter_obj->source));
|
|
|
|
|
|
|
|
|
|
if (symtab == NULL)
|
|
|
|
|
Py_RETURN_FALSE;
|
|
|
|
|
|
|
|
|
|
Py_RETURN_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static PyMethodDef linetable_object_methods[] = {
|
|
|
|
|
{ "line", ltpy_get_pcs_for_line, METH_VARARGS,
|
|
|
|
|
"line (lineno) -> Tuple\n\
|
|
|
|
|
Return executable locations for a given source line." },
|
|
|
|
|
{ "has_line", ltpy_has_line, METH_VARARGS,
|
|
|
|
|
"has_line (lineno) -> Boolean\n\
|
|
|
|
|
Return TRUE if this line has executable information, FALSE if not." },
|
|
|
|
|
{ "source_lines", ltpy_get_all_source_lines, METH_NOARGS,
|
2015-07-23 15:36:25 +02:00
|
|
|
|
"source_lines () -> List\n\
|
|
|
|
|
Return a list of all executable source lines." },
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{ "is_valid", ltpy_is_valid, METH_NOARGS,
|
|
|
|
|
"is_valid () -> Boolean.\n\
|
2015-08-04 18:03:15 +02:00
|
|
|
|
Return True if this LineTable is valid, False if not." },
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{NULL} /* Sentinel */
|
|
|
|
|
};
|
|
|
|
|
|
Fix redefinition errors in C++ mode
In C, we can forward declare static structure instances. That doesn't
work in C++ though. C++ treats these as definitions. So then the
compiler complains about symbol redefinition, like:
src/gdb/elfread.c:1569:29: error: redefinition of ‘const sym_fns elf_sym_fns_lazy_psyms’
src/gdb/elfread.c:53:29: error: ‘const sym_fns elf_sym_fns_lazy_psyms’ previously declared here
The intent of static here is naturally to avoid making these objects
visible outside the compilation unit. The equivalent in C++ would be
to instead define the objects in the anonymous namespace. But given
that it's desirable to leave the codebase compiling as both C and C++
for a while, this just makes the objects extern.
(base_breakpoint_ops is already declared in breakpoint.h, so we can
just remove the forward declare from breakpoint.c)
gdb/ChangeLog:
2015-02-11 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
* breakpoint.c (base_breakpoint_ops): Delete.
* dwarf2loc.c (dwarf_expr_ctx_funcs): Make extern.
* elfread.c (elf_sym_fns_gdb_index, elf_sym_fns_lazy_psyms): Make extern.
* guile/guile.c (guile_extension_script_ops, guile_extension_ops): Make extern.
* ppcnbsd-tdep.c (ppcnbsd2_sigtramp): Make extern.
* python/py-arch.c (arch_object_type): Make extern.
* python/py-block.c (block_syms_iterator_object_type): Make extern.
* python/py-bpevent.c (breakpoint_event_object_type): Make extern.
* python/py-cmd.c (cmdpy_object_type): Make extern.
* python/py-continueevent.c (continue_event_object_type)
* python/py-event.h (GDBPY_NEW_EVENT_TYPE): Remove 'qual'
parameter. Update all callers.
* python/py-evtregistry.c (eventregistry_object_type): Make extern.
* python/py-exitedevent.c (exited_event_object_type): Make extern.
* python/py-finishbreakpoint.c (finish_breakpoint_object_type): Make extern.
* python/py-function.c (fnpy_object_type): Make extern.
* python/py-inferior.c (inferior_object_type, membuf_object_type): Make extern.
* python/py-infevents.c (call_pre_event_object_type)
(inferior_call_post_event_object_type).
(memory_changed_event_object_type): Make extern.
* python/py-infthread.c (thread_object_type): Make extern.
* python/py-lazy-string.c (lazy_string_object_type): Make extern.
* python/py-linetable.c (linetable_entry_object_type)
(linetable_object_type, ltpy_iterator_object_type): Make extern.
* python/py-newobjfileevent.c (new_objfile_event_object_type)
(clear_objfiles_event_object_type): Make extern.
* python/py-objfile.c (objfile_object_type): Make extern.
* python/py-param.c (parmpy_object_type): Make extern.
* python/py-progspace.c (pspace_object_type): Make extern.
* python/py-signalevent.c (signal_event_object_type): Make extern.
* python/py-symtab.c (symtab_object_type, sal_object_type): Make extern.
* python/py-type.c (type_object_type, field_object_type)
(type_iterator_object_type): Make extern.
* python/python.c (python_extension_script_ops)
(python_extension_ops): Make extern.
* stap-probe.c (stap_probe_ops): Make extern.
2015-02-11 12:20:21 +01:00
|
|
|
|
PyTypeObject linetable_object_type = {
|
2013-11-11 20:49:45 +01:00
|
|
|
|
PyVarObject_HEAD_INIT (NULL, 0)
|
|
|
|
|
"gdb.LineTable", /*tp_name*/
|
|
|
|
|
sizeof (linetable_object), /*tp_basicsize*/
|
|
|
|
|
0, /*tp_itemsize*/
|
|
|
|
|
ltpy_dealloc, /*tp_dealloc*/
|
|
|
|
|
0, /*tp_print*/
|
|
|
|
|
0, /*tp_getattr*/
|
|
|
|
|
0, /*tp_setattr*/
|
|
|
|
|
0, /*tp_compare*/
|
|
|
|
|
0, /*tp_repr*/
|
|
|
|
|
0, /*tp_as_number*/
|
|
|
|
|
0, /*tp_as_sequence*/
|
|
|
|
|
0, /*tp_as_mapping*/
|
|
|
|
|
0, /*tp_hash */
|
|
|
|
|
0, /*tp_call*/
|
|
|
|
|
0, /*tp_str*/
|
|
|
|
|
0, /*tp_getattro*/
|
|
|
|
|
0, /*tp_setattro*/
|
|
|
|
|
0, /*tp_as_buffer*/
|
|
|
|
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
|
|
|
|
"GDB line table object", /* tp_doc */
|
|
|
|
|
0, /* tp_traverse */
|
|
|
|
|
0, /* tp_clear */
|
|
|
|
|
0, /* tp_richcompare */
|
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
|
ltpy_iter, /* tp_iter */
|
|
|
|
|
0, /* tp_iternext */
|
|
|
|
|
linetable_object_methods, /* tp_methods */
|
|
|
|
|
0, /* tp_members */
|
|
|
|
|
0, /* tp_getset */
|
|
|
|
|
0, /* tp_base */
|
|
|
|
|
0, /* tp_dict */
|
|
|
|
|
0, /* tp_descr_get */
|
|
|
|
|
0, /* tp_descr_set */
|
|
|
|
|
0, /* tp_dictoffset */
|
|
|
|
|
0, /* tp_init */
|
|
|
|
|
0, /* tp_alloc */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static PyMethodDef ltpy_iterator_methods[] = {
|
|
|
|
|
{ "is_valid", ltpy_iter_is_valid, METH_NOARGS,
|
|
|
|
|
"is_valid () -> Boolean.\n\
|
2015-08-04 18:03:15 +02:00
|
|
|
|
Return True if this LineTable iterator is valid, False if not." },
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{NULL} /* Sentinel */
|
|
|
|
|
};
|
|
|
|
|
|
Fix redefinition errors in C++ mode
In C, we can forward declare static structure instances. That doesn't
work in C++ though. C++ treats these as definitions. So then the
compiler complains about symbol redefinition, like:
src/gdb/elfread.c:1569:29: error: redefinition of ‘const sym_fns elf_sym_fns_lazy_psyms’
src/gdb/elfread.c:53:29: error: ‘const sym_fns elf_sym_fns_lazy_psyms’ previously declared here
The intent of static here is naturally to avoid making these objects
visible outside the compilation unit. The equivalent in C++ would be
to instead define the objects in the anonymous namespace. But given
that it's desirable to leave the codebase compiling as both C and C++
for a while, this just makes the objects extern.
(base_breakpoint_ops is already declared in breakpoint.h, so we can
just remove the forward declare from breakpoint.c)
gdb/ChangeLog:
2015-02-11 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
* breakpoint.c (base_breakpoint_ops): Delete.
* dwarf2loc.c (dwarf_expr_ctx_funcs): Make extern.
* elfread.c (elf_sym_fns_gdb_index, elf_sym_fns_lazy_psyms): Make extern.
* guile/guile.c (guile_extension_script_ops, guile_extension_ops): Make extern.
* ppcnbsd-tdep.c (ppcnbsd2_sigtramp): Make extern.
* python/py-arch.c (arch_object_type): Make extern.
* python/py-block.c (block_syms_iterator_object_type): Make extern.
* python/py-bpevent.c (breakpoint_event_object_type): Make extern.
* python/py-cmd.c (cmdpy_object_type): Make extern.
* python/py-continueevent.c (continue_event_object_type)
* python/py-event.h (GDBPY_NEW_EVENT_TYPE): Remove 'qual'
parameter. Update all callers.
* python/py-evtregistry.c (eventregistry_object_type): Make extern.
* python/py-exitedevent.c (exited_event_object_type): Make extern.
* python/py-finishbreakpoint.c (finish_breakpoint_object_type): Make extern.
* python/py-function.c (fnpy_object_type): Make extern.
* python/py-inferior.c (inferior_object_type, membuf_object_type): Make extern.
* python/py-infevents.c (call_pre_event_object_type)
(inferior_call_post_event_object_type).
(memory_changed_event_object_type): Make extern.
* python/py-infthread.c (thread_object_type): Make extern.
* python/py-lazy-string.c (lazy_string_object_type): Make extern.
* python/py-linetable.c (linetable_entry_object_type)
(linetable_object_type, ltpy_iterator_object_type): Make extern.
* python/py-newobjfileevent.c (new_objfile_event_object_type)
(clear_objfiles_event_object_type): Make extern.
* python/py-objfile.c (objfile_object_type): Make extern.
* python/py-param.c (parmpy_object_type): Make extern.
* python/py-progspace.c (pspace_object_type): Make extern.
* python/py-signalevent.c (signal_event_object_type): Make extern.
* python/py-symtab.c (symtab_object_type, sal_object_type): Make extern.
* python/py-type.c (type_object_type, field_object_type)
(type_iterator_object_type): Make extern.
* python/python.c (python_extension_script_ops)
(python_extension_ops): Make extern.
* stap-probe.c (stap_probe_ops): Make extern.
2015-02-11 12:20:21 +01:00
|
|
|
|
PyTypeObject ltpy_iterator_object_type = {
|
2013-11-11 20:49:45 +01:00
|
|
|
|
PyVarObject_HEAD_INIT (NULL, 0)
|
|
|
|
|
"gdb.LineTableIterator", /*tp_name*/
|
|
|
|
|
sizeof (ltpy_iterator_object), /*tp_basicsize*/
|
|
|
|
|
0, /*tp_itemsize*/
|
|
|
|
|
ltpy_iterator_dealloc, /*tp_dealloc*/
|
|
|
|
|
0, /*tp_print*/
|
|
|
|
|
0, /*tp_getattr*/
|
|
|
|
|
0, /*tp_setattr*/
|
|
|
|
|
0, /*tp_compare*/
|
|
|
|
|
0, /*tp_repr*/
|
|
|
|
|
0, /*tp_as_number*/
|
|
|
|
|
0, /*tp_as_sequence*/
|
|
|
|
|
0, /*tp_as_mapping*/
|
|
|
|
|
0, /*tp_hash */
|
|
|
|
|
0, /*tp_call*/
|
|
|
|
|
0, /*tp_str*/
|
|
|
|
|
0, /*tp_getattro*/
|
|
|
|
|
0, /*tp_setattro*/
|
|
|
|
|
0, /*tp_as_buffer*/
|
|
|
|
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
|
|
|
|
|
"GDB line table iterator object", /*tp_doc */
|
|
|
|
|
0, /*tp_traverse */
|
|
|
|
|
0, /*tp_clear */
|
|
|
|
|
0, /*tp_richcompare */
|
|
|
|
|
0, /*tp_weaklistoffset */
|
|
|
|
|
ltpy_iterator, /*tp_iter */
|
|
|
|
|
ltpy_iternext, /*tp_iternext */
|
|
|
|
|
ltpy_iterator_methods /*tp_methods */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
-Wwrite-strings: Wrap PyGetSetDef for construction with string literals
Unfortunately, PyGetSetDef's 'name' and 'doc' members are 'char *'
instead of 'const char *', meaning that in order to list-initialize
PyGetSetDef arrays using string literals requires writing explicit
'char *' casts. For example:
static PyGetSetDef value_object_getset[] = {
- { "address", valpy_get_address, NULL, "The address of the value.",
+ { (char *) "address", valpy_get_address, NULL,
+ (char *) "The address of the value.",
NULL },
- { "is_optimized_out", valpy_get_is_optimized_out, NULL,
- "Boolean telling whether the value is optimized "
+ { (char *) "is_optimized_out", valpy_get_is_optimized_out, NULL,
+ (char *) "Boolean telling whether the value is optimized "
"out (i.e., not available).",
NULL },
- { "type", valpy_get_type, NULL, "Type of the value.", NULL },
- { "dynamic_type", valpy_get_dynamic_type, NULL,
- "Dynamic type of the value.", NULL },
- { "is_lazy", valpy_get_is_lazy, NULL,
- "Boolean telling whether the value is lazy (not fetched yet\n\
+ { (char *) "type", valpy_get_type, NULL,
+ (char *) "Type of the value.", NULL },
+ { (char *) "dynamic_type", valpy_get_dynamic_type, NULL,
+ (char *) "Dynamic type of the value.", NULL },
+ { (char *) "is_lazy", valpy_get_is_lazy, NULL,
+ (char *) "Boolean telling whether the value is lazy (not fetched yet\n\
from the inferior). A lazy value is fetched when needed, or when\n\
the \"fetch_lazy()\" method is called.", NULL },
{NULL} /* Sentinel */
We have ~20 such arrays, and I first wrote a patch that fixed all of
them like that... It's not pretty...
One way to make these a bit less ugly would be add a new macro that
hides the casts, like:
#define GDBPY_GSDEF(NAME, GET, SET, DOC, CLOSURE) \
{ (char *) NAME, GET, SET, (char *) DOC, CLOSURE }
and then use it like:
static PyGetSetDef value_object_getset[] = {
GDBPY_GSDEF ("address", valpy_get_address, NULL,
"The address of the value.", NULL),
GDBPY_GSDEF ("is_optimized_out", valpy_get_is_optimized_out, NULL,
"Boolean telling whether the value is optimized ", NULL),
{NULL} /* Sentinel */
};
But since we have C++11, which gives us constexpr and list
initialization, I thought of a way that requires no changes where the
arrays are initialized:
We add a new type that extends PyGetSetDef (called gdb_PyGetSetDef),
and add constexpr constructors that accept const 'name' and 'doc', and
then list/aggregate initialization simply "calls" these matching
constructors instead.
I put "calls" in quotes, because given "constexpr", it's all done at
compile time, and there's no overhead either in binary size or at run
time. In fact, we get identical binaries, before/after this change.
Unlike the fixes that fix some old Python API to match the API of more
recent Python, this switches to using explicit "gdb_PyGetSetDef"
everywhere, just to be clear that we are using our own version of it.
gdb/ChangeLog:
2017-04-05 Pedro Alves <palves@redhat.com>
* python/python-internal.h (gdb_PyGetSetDef): New type.
* python/py-block.c (block_object_getset)
(breakpoint_object_getset): Now a gdb_PyGetSetDef array.
* python/py-event.c (event_object_getset)
(finish_breakpoint_object_getset): Likewise.
* python/py-inferior.c (inferior_object_getset): Likewise.
* python/py-infthread.c (thread_object_getset): Likewise.
* python/py-lazy-string.c (lazy_string_object_getset): Likewise.
* python/py-linetable.c (linetable_entry_object_getset): Likewise.
* python/py-objfile.c (objfile_getset): Likewise.
* python/py-progspace.c (pspace_getset): Likewise.
* python/py-record-btrace.c (btpy_insn_getset, btpy_call_getset):
Likewise.
* python/py-record.c (recpy_record_getset): Likewise.
* python/py-symbol.c (symbol_object_getset): Likewise.
* python/py-symtab.c (symtab_object_getset, sal_object_getset):
Likewise.
* python/py-type.c (type_object_getset, field_object_getset):
Likewise.
* python/py-value.c (value_object_getset): Likewise.
2017-04-05 20:21:36 +02:00
|
|
|
|
static gdb_PyGetSetDef linetable_entry_object_getset[] = {
|
2013-11-11 20:49:45 +01:00
|
|
|
|
{ "line", ltpy_entry_get_line, NULL,
|
|
|
|
|
"The line number in the source file.", NULL },
|
|
|
|
|
{ "pc", ltpy_entry_get_pc, NULL,
|
|
|
|
|
"The memory address for this line number.", NULL },
|
|
|
|
|
{ NULL } /* Sentinel */
|
|
|
|
|
};
|
|
|
|
|
|
Fix redefinition errors in C++ mode
In C, we can forward declare static structure instances. That doesn't
work in C++ though. C++ treats these as definitions. So then the
compiler complains about symbol redefinition, like:
src/gdb/elfread.c:1569:29: error: redefinition of ‘const sym_fns elf_sym_fns_lazy_psyms’
src/gdb/elfread.c:53:29: error: ‘const sym_fns elf_sym_fns_lazy_psyms’ previously declared here
The intent of static here is naturally to avoid making these objects
visible outside the compilation unit. The equivalent in C++ would be
to instead define the objects in the anonymous namespace. But given
that it's desirable to leave the codebase compiling as both C and C++
for a while, this just makes the objects extern.
(base_breakpoint_ops is already declared in breakpoint.h, so we can
just remove the forward declare from breakpoint.c)
gdb/ChangeLog:
2015-02-11 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
* breakpoint.c (base_breakpoint_ops): Delete.
* dwarf2loc.c (dwarf_expr_ctx_funcs): Make extern.
* elfread.c (elf_sym_fns_gdb_index, elf_sym_fns_lazy_psyms): Make extern.
* guile/guile.c (guile_extension_script_ops, guile_extension_ops): Make extern.
* ppcnbsd-tdep.c (ppcnbsd2_sigtramp): Make extern.
* python/py-arch.c (arch_object_type): Make extern.
* python/py-block.c (block_syms_iterator_object_type): Make extern.
* python/py-bpevent.c (breakpoint_event_object_type): Make extern.
* python/py-cmd.c (cmdpy_object_type): Make extern.
* python/py-continueevent.c (continue_event_object_type)
* python/py-event.h (GDBPY_NEW_EVENT_TYPE): Remove 'qual'
parameter. Update all callers.
* python/py-evtregistry.c (eventregistry_object_type): Make extern.
* python/py-exitedevent.c (exited_event_object_type): Make extern.
* python/py-finishbreakpoint.c (finish_breakpoint_object_type): Make extern.
* python/py-function.c (fnpy_object_type): Make extern.
* python/py-inferior.c (inferior_object_type, membuf_object_type): Make extern.
* python/py-infevents.c (call_pre_event_object_type)
(inferior_call_post_event_object_type).
(memory_changed_event_object_type): Make extern.
* python/py-infthread.c (thread_object_type): Make extern.
* python/py-lazy-string.c (lazy_string_object_type): Make extern.
* python/py-linetable.c (linetable_entry_object_type)
(linetable_object_type, ltpy_iterator_object_type): Make extern.
* python/py-newobjfileevent.c (new_objfile_event_object_type)
(clear_objfiles_event_object_type): Make extern.
* python/py-objfile.c (objfile_object_type): Make extern.
* python/py-param.c (parmpy_object_type): Make extern.
* python/py-progspace.c (pspace_object_type): Make extern.
* python/py-signalevent.c (signal_event_object_type): Make extern.
* python/py-symtab.c (symtab_object_type, sal_object_type): Make extern.
* python/py-type.c (type_object_type, field_object_type)
(type_iterator_object_type): Make extern.
* python/python.c (python_extension_script_ops)
(python_extension_ops): Make extern.
* stap-probe.c (stap_probe_ops): Make extern.
2015-02-11 12:20:21 +01:00
|
|
|
|
PyTypeObject linetable_entry_object_type = {
|
2013-11-11 20:49:45 +01:00
|
|
|
|
PyVarObject_HEAD_INIT (NULL, 0)
|
|
|
|
|
"gdb.LineTableEntry", /*tp_name*/
|
|
|
|
|
sizeof (linetable_entry_object), /*tp_basicsize*/
|
|
|
|
|
0, /*tp_itemsize*/
|
|
|
|
|
0, /*tp_dealloc*/
|
|
|
|
|
0, /*tp_print*/
|
|
|
|
|
0, /*tp_getattr*/
|
|
|
|
|
0, /*tp_setattr*/
|
|
|
|
|
0, /*tp_compare*/
|
|
|
|
|
0, /*tp_repr*/
|
|
|
|
|
0, /*tp_as_number*/
|
|
|
|
|
0, /*tp_as_sequence*/
|
|
|
|
|
0, /*tp_as_mapping*/
|
|
|
|
|
0, /*tp_hash */
|
|
|
|
|
0, /*tp_call*/
|
|
|
|
|
0, /*tp_str*/
|
|
|
|
|
0, /*tp_getattro*/
|
|
|
|
|
0, /*tp_setattro*/
|
|
|
|
|
0, /*tp_as_buffer*/
|
|
|
|
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
|
|
|
|
"GDB line table entry object", /* tp_doc */
|
|
|
|
|
0, /* tp_traverse */
|
|
|
|
|
0, /* tp_clear */
|
|
|
|
|
0, /* tp_richcompare */
|
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
|
0, /* tp_iter */
|
|
|
|
|
0, /* tp_iternext */
|
|
|
|
|
0, /* tp_methods */
|
|
|
|
|
0, /* tp_members */
|
|
|
|
|
linetable_entry_object_getset, /* tp_getset */
|
|
|
|
|
0, /* tp_base */
|
|
|
|
|
0, /* tp_dict */
|
|
|
|
|
0, /* tp_descr_get */
|
|
|
|
|
0, /* tp_descr_set */
|
|
|
|
|
0, /* tp_dictoffset */
|
|
|
|
|
0, /* tp_init */
|
|
|
|
|
0, /* tp_alloc */
|
|
|
|
|
};
|