diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2017-09-22 17:00:33 -0300 |
---|---|---|
committer | Alexandre Oliva <aoliva@redhat.com> | 2017-09-22 17:00:33 -0300 |
commit | 9e0703de64a6dd4deae2ebd569955f14337f2710 (patch) | |
tree | cec45139f1febef6441deabae142c3fb3f2c61f3 /gdb/python | |
parent | 13b9f79a1904081d984a64037af6457c1e3ff7b6 (diff) | |
parent | 43573013c9836f2b91b74b9b29dac35fdb41e06b (diff) | |
download | gdb-9e0703de64a6dd4deae2ebd569955f14337f2710.zip gdb-9e0703de64a6dd4deae2ebd569955f14337f2710.tar.gz gdb-9e0703de64a6dd4deae2ebd569955f14337f2710.tar.bz2 |
Merge remote-tracking branch 'remotes/master' into users/aoliva/SFN
Updated local changes to binutils/testsuite/binutils-all/readelf.exp
to match the unresolved (failed to assemble) messages introduced by
Alan Modra.
Diffstat (limited to 'gdb/python')
-rw-r--r-- | gdb/python/py-all-events.def | 40 | ||||
-rw-r--r-- | gdb/python/py-bpevent.c | 13 | ||||
-rw-r--r-- | gdb/python/py-breakpoint.c | 17 | ||||
-rw-r--r-- | gdb/python/py-cmd.c | 66 | ||||
-rw-r--r-- | gdb/python/py-continueevent.c | 11 | ||||
-rw-r--r-- | gdb/python/py-event-types.def | 107 | ||||
-rw-r--r-- | gdb/python/py-event.c | 4 | ||||
-rw-r--r-- | gdb/python/py-event.h | 79 | ||||
-rw-r--r-- | gdb/python/py-events.h | 19 | ||||
-rw-r--r-- | gdb/python/py-evts.c | 43 | ||||
-rw-r--r-- | gdb/python/py-exitedevent.c | 10 | ||||
-rw-r--r-- | gdb/python/py-frame.c | 17 | ||||
-rw-r--r-- | gdb/python/py-inferior.c | 119 | ||||
-rw-r--r-- | gdb/python/py-infevents.c | 38 | ||||
-rw-r--r-- | gdb/python/py-newobjfileevent.c | 16 | ||||
-rw-r--r-- | gdb/python/py-param.c | 24 | ||||
-rw-r--r-- | gdb/python/py-record-btrace.c | 2 | ||||
-rw-r--r-- | gdb/python/py-signalevent.c | 13 | ||||
-rw-r--r-- | gdb/python/py-stopevent.c | 16 | ||||
-rw-r--r-- | gdb/python/py-stopevent.h | 8 | ||||
-rw-r--r-- | gdb/python/py-threadevent.c | 23 | ||||
-rw-r--r-- | gdb/python/py-type.c | 8 | ||||
-rw-r--r-- | gdb/python/py-unwind.c | 2 | ||||
-rw-r--r-- | gdb/python/py-value.c | 3 | ||||
-rw-r--r-- | gdb/python/py-varobj.c | 9 | ||||
-rw-r--r-- | gdb/python/python-internal.h | 31 | ||||
-rw-r--r-- | gdb/python/python.c | 179 |
27 files changed, 462 insertions, 455 deletions
diff --git a/gdb/python/py-all-events.def b/gdb/python/py-all-events.def new file mode 100644 index 0000000..cdede6b --- /dev/null +++ b/gdb/python/py-all-events.def @@ -0,0 +1,40 @@ +/* Python event definitions -*- c++ -*- + + Copyright (C) 2017 Free Software Foundation, Inc. + + 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/>. */ + +/* To use this file, define GDB_PY_DEFINE_EVENT to expand how you + like, then include the file. + + GDB_PY_DEFINE_EVENT has one parameter, the name of the event. +*/ + +GDB_PY_DEFINE_EVENT(stop) +GDB_PY_DEFINE_EVENT(cont) +GDB_PY_DEFINE_EVENT(exited) +GDB_PY_DEFINE_EVENT(new_objfile) +GDB_PY_DEFINE_EVENT(clear_objfiles) +GDB_PY_DEFINE_EVENT(new_inferior) +GDB_PY_DEFINE_EVENT(inferior_deleted) +GDB_PY_DEFINE_EVENT(new_thread) +GDB_PY_DEFINE_EVENT(inferior_call) +GDB_PY_DEFINE_EVENT(memory_changed) +GDB_PY_DEFINE_EVENT(register_changed) +GDB_PY_DEFINE_EVENT(breakpoint_created) +GDB_PY_DEFINE_EVENT(breakpoint_deleted) +GDB_PY_DEFINE_EVENT(breakpoint_modified) +GDB_PY_DEFINE_EVENT(before_prompt) diff --git a/gdb/python/py-bpevent.c b/gdb/python/py-bpevent.c index c5a85b6..1cb3f9a 100644 --- a/gdb/python/py-bpevent.c +++ b/gdb/python/py-bpevent.c @@ -21,13 +21,10 @@ #include "py-stopevent.h" #include "py-ref.h" -extern PyTypeObject breakpoint_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - /* Create and initialize a BreakpointEvent object. This acquires new references to BREAKPOINT_LIST and FIRST_BP. */ -PyObject * +gdbpy_ref<> create_breakpoint_event_object (PyObject *breakpoint_list, PyObject *first_bp) { gdbpy_ref<> breakpoint_event_obj @@ -45,11 +42,5 @@ create_breakpoint_event_object (PyObject *breakpoint_list, PyObject *first_bp) breakpoint_list) < 0) return NULL; - return breakpoint_event_obj.release (); + return breakpoint_event_obj; } - -GDBPY_NEW_EVENT_TYPE (breakpoint, - "gdb.BreakpointEvent", - "BreakpointEvent", - "GDB breakpoint stop event object", - stop_event_object_type); diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 64de803..d57c2fa 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -673,7 +673,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) TRY { gdb::unique_xmalloc_ptr<char> - copy_holder (xstrdup (skip_spaces_const (spec))); + copy_holder (xstrdup (skip_spaces (spec))); char *copy = copy_holder.get (); switch (type) @@ -1026,15 +1026,12 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v) extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON); if (extlang != NULL) { - char *error_text; - - error_text - = xstrprintf (_("Only one stop condition allowed. There is" - " currently a %s stop condition defined for" - " this breakpoint."), - ext_lang_capitalized_name (extlang)); - PyErr_SetString (PyExc_RuntimeError, error_text); - xfree (error_text); + std::string error_text + = string_printf (_("Only one stop condition allowed. There is" + " currently a %s stop condition defined for" + " this breakpoint."), + ext_lang_capitalized_name (extlang)); + PyErr_SetString (PyExc_RuntimeError, error_text.c_str ()); return -1; } } diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 6203211..2a7c613 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -44,7 +44,7 @@ static const struct cmdpy_completer completers[] = { "COMPLETE_FILENAME", filename_completer }, { "COMPLETE_LOCATION", location_completer }, { "COMPLETE_COMMAND", command_completer }, - { "COMPLETE_SYMBOL", make_symbol_completion_list_fn }, + { "COMPLETE_SYMBOL", symbol_completer }, { "COMPLETE_EXPRESSION", expression_completer }, }; @@ -242,10 +242,21 @@ cmdpy_completer_helper (struct cmd_list_element *command, NULL)); if (textobj == NULL) error (_("Could not convert argument to Python string.")); - gdbpy_ref<> wordobj (PyUnicode_Decode (word, strlen (word), host_charset (), - NULL)); - if (wordobj == NULL) - error (_("Could not convert argument to Python string.")); + + gdbpy_ref<> wordobj; + if (word == NULL) + { + /* "brkchars" phase. */ + wordobj.reset (Py_None); + Py_INCREF (Py_None); + } + else + { + wordobj.reset (PyUnicode_Decode (word, strlen (word), host_charset (), + NULL)); + if (wordobj == NULL) + error (_("Could not convert argument to Python string.")); + } gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst, @@ -267,6 +278,7 @@ cmdpy_completer_helper (struct cmd_list_element *command, static void cmdpy_completer_handle_brkchars (struct cmd_list_element *command, + completion_tracker &tracker, const char *text, const char *word) { gdbpy_enter enter_py (get_current_arch (), current_language); @@ -293,23 +305,25 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command, } else if (value >= 0 && value < (long) N_COMPLETERS) { + completer_handle_brkchars_ftype *brkchars_fn; + /* This is the core of this function. Depending on which completer type the Python function returns, we have to adjust the break characters accordingly. */ - set_gdb_completion_word_break_characters - (completers[value].completer); + brkchars_fn = (completer_handle_brkchars_func_for_completer + (completers[value].completer)); + brkchars_fn (command, tracker, text, word); } } } /* Called by gdb for command completion. */ -static VEC (char_ptr) * +static void cmdpy_completer (struct cmd_list_element *command, + completion_tracker &tracker, const char *text, const char *word) { - VEC (char_ptr) *result = NULL; - gdbpy_enter enter_py (get_current_arch (), current_language); /* Calling our helper to obtain the PyObject of the Python @@ -317,12 +331,10 @@ cmdpy_completer (struct cmd_list_element *command, gdbpy_ref<> resultobj (cmdpy_completer_helper (command, text, word)); /* If the result object of calling the Python function is NULL, it - means that there was an error. In this case, just give up and - return NULL. */ + means that there was an error. In this case, just give up. */ if (resultobj == NULL) - return NULL; + return; - result = NULL; if (PyInt_Check (resultobj.get ())) { /* User code may also return one of the completion constants, @@ -335,15 +347,16 @@ cmdpy_completer (struct cmd_list_element *command, PyErr_Clear (); } else if (value >= 0 && value < (long) N_COMPLETERS) - result = completers[value].completer (command, text, word); + completers[value].completer (command, tracker, text, word); } else { gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ())); if (iter == NULL) - return NULL; + return; + bool got_matches = false; while (true) { gdbpy_ref<> elt (PyIter_Next (iter.get ())); @@ -363,16 +376,15 @@ cmdpy_completer (struct cmd_list_element *command, PyErr_Clear (); continue; } - VEC_safe_push (char_ptr, result, item.release ()); + tracker.add_completion (std::move (item)); + got_matches = true; } /* If we got some results, ignore problems. Otherwise, report the problem. */ - if (result != NULL && PyErr_Occurred ()) + if (got_matches && PyErr_Occurred ()) PyErr_Clear (); } - - return result; } /* Helper for cmdpy_init which locates the command list to use and @@ -763,22 +775,16 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args) if (*input != '\0') { - char **c_argv = gdb_buildargv (input); - int i; + gdb_argv c_argv (input); - for (i = 0; c_argv[i] != NULL; ++i) + for (char *arg : c_argv) { - gdbpy_ref<> argp (PyString_FromString (c_argv[i])); + gdbpy_ref<> argp (PyString_FromString (arg)); if (argp == NULL || PyList_Append (py_argv.get (), argp.get ()) < 0) - { - freeargv (c_argv); - return NULL; - } + return NULL; } - - freeargv (c_argv); } return py_argv.release (); diff --git a/gdb/python/py-continueevent.c b/gdb/python/py-continueevent.c index 8be28c2..8c704b9 100644 --- a/gdb/python/py-continueevent.c +++ b/gdb/python/py-continueevent.c @@ -21,10 +21,7 @@ #include "py-event.h" #include "py-ref.h" -extern PyTypeObject continue_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - -static PyObject * +static gdbpy_ref<> create_continue_event_object (void) { return create_thread_event_object (&continue_event_object_type); @@ -45,9 +42,3 @@ emit_continue_event (ptid_t ptid) return evpy_emit_event (event.get (), gdb_py_events.cont); return -1; } - -GDBPY_NEW_EVENT_TYPE (continue, - "gdb.ContinueEvent", - "ContinueEvent", - "GDB continue event object", - thread_event_object_type); diff --git a/gdb/python/py-event-types.def b/gdb/python/py-event-types.def new file mode 100644 index 0000000..f571f66 --- /dev/null +++ b/gdb/python/py-event-types.def @@ -0,0 +1,107 @@ +/* Python event definitions -*- c++ -*- + + Copyright (C) 2017 Free Software Foundation, Inc. + + 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/>. */ + +/* To use this file, define GDB_PY_DEFINE_EVENT_TYPE to expand how you + like, then include the file. + + Each invocation is of the form: + + GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) + + NAME is the name of the event. + PY_NAME a string representing what the event should be called in + python. + DOC Python documentation for the new event type + BASE the base event for this event usually just event_object_type. +*/ + +GDB_PY_DEFINE_EVENT_TYPE (breakpoint, + "BreakpointEvent", + "GDB breakpoint stop event object", + stop_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (continue, + "ContinueEvent", + "GDB continue event object", + thread_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (exited, + "ExitedEvent", + "GDB exited event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (new_thread, + "NewThreadEvent", + "GDB new thread event object", + thread_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (new_inferior, + "NewInferiorEvent", + "GDB new inferior event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (inferior_deleted, + "InferiorDeletedEvent", + "GDB inferior deleted event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (inferior_call_pre, + "InferiorCallPreEvent", + "GDB inferior function pre-call event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (inferior_call_post, + "InferiorCallPostEvent", + "GDB inferior function post-call event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (register_changed, + "RegisterChangedEvent", + "GDB register change event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (memory_changed, + "MemoryChangedEvent", + "GDB memory change event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (new_objfile, + "NewObjFileEvent", + "GDB new object file event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (clear_objfiles, + "ClearObjFilesEvent", + "GDB clear object files event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (signal, + "SignalEvent", + "GDB signal event object", + stop_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (stop, + "StopEvent", + "GDB stop event object", + thread_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (thread, + "ThreadEvent", + "GDB thread event object", + event_object_type); diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c index b349891..9d84e33 100644 --- a/gdb/python/py-event.c +++ b/gdb/python/py-event.c @@ -27,7 +27,7 @@ evpy_dealloc (PyObject *self) Py_TYPE (self)->tp_free (self); } -PyObject * +gdbpy_ref<> create_event_object (PyTypeObject *py_type) { gdbpy_ref<event_object> event_obj (PyObject_New (event_object, py_type)); @@ -38,7 +38,7 @@ create_event_object (PyTypeObject *py_type) if (!event_obj->dict) return NULL; - return (PyObject*) event_obj.release (); + return gdbpy_ref<> ((PyObject *) event_obj.release ()); } /* Add the attribute ATTR to the event object EVENT. In diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index ccb8513..2444260 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -26,74 +26,12 @@ #include "inferior.h" #include "py-ref.h" -/* This macro creates the following functions: - - gdbpy_initialize_{NAME}_event - Used to add the newly created event type to the gdb module. - - and the python type data structure for the event: - - struct PyTypeObject {NAME}_event_object_type - - NAME is the name of the event. - PY_PATH is a string representing the module and python name of - the event. - PY_NAME a string representing what the event should be called in - python. - DOC Python documentation for the new event type - BASE the base event for this event usually just event_object_type. -*/ - -#define GDBPY_NEW_EVENT_TYPE(name, py_path, py_name, doc, base) \ -\ - PyTypeObject name##_event_object_type \ - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object") \ - = { \ - PyVarObject_HEAD_INIT (NULL, 0) \ - py_path, /* tp_name */ \ - sizeof (event_object), /* tp_basicsize */ \ - 0, /* tp_itemsize */ \ - evpy_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_BASETYPE, /* tp_flags */ \ - doc, /* 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 */ \ - 0, /* tp_getset */ \ - &base, /* tp_base */ \ - 0, /* tp_dict */ \ - 0, /* tp_descr_get */ \ - 0, /* tp_descr_set */ \ - 0, /* tp_dictoffset */ \ - 0, /* tp_init */ \ - 0 /* tp_alloc */ \ - }; \ -\ -int \ -gdbpy_initialize_##name##_event (void) \ -{ \ - return gdbpy_initialize_event_generic (&name##_event_object_type, \ - py_name); \ -} +/* Declare all event types. */ +#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \ + extern PyTypeObject name##_event_object_type \ + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); +#include "py-event-types.def" +#undef GDB_PY_DEFINE_EVENT_TYPE typedef struct { @@ -124,8 +62,9 @@ extern int emit_memory_changed_event (CORE_ADDR addr, ssize_t len); extern int evpy_emit_event (PyObject *event, eventregistry_object *registry); -extern PyObject *create_event_object (PyTypeObject *py_type); -extern PyObject *create_thread_event_object (PyTypeObject *py_type); +extern gdbpy_ref<> create_event_object (PyTypeObject *py_type); +extern gdbpy_ref<> create_thread_event_object (PyTypeObject *py_type, + PyObject *thread = nullptr); extern int emit_new_objfile_event (struct objfile *objfile); extern int emit_clear_objfiles_event (void); diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h index 348dabc..876b564 100644 --- a/gdb/python/py-events.h +++ b/gdb/python/py-events.h @@ -24,9 +24,6 @@ #include "python-internal.h" #include "inferior.h" -extern PyTypeObject thread_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - /* Stores a list of objects to be notified when the event for which this registry tracks occurs. */ @@ -42,18 +39,10 @@ typedef struct typedef struct { - eventregistry_object *stop; - eventregistry_object *cont; - eventregistry_object *exited; - eventregistry_object *new_objfile; - eventregistry_object *clear_objfiles; - eventregistry_object *inferior_call; - eventregistry_object *memory_changed; - eventregistry_object *register_changed; - eventregistry_object *breakpoint_created; - eventregistry_object *breakpoint_deleted; - eventregistry_object *breakpoint_modified; - eventregistry_object *before_prompt; +#define GDB_PY_DEFINE_EVENT(name) \ + eventregistry_object *name; +#include "py-all-events.def" +#undef GDB_PY_DEFINE_EVENT PyObject *module; diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c index 126d18c..0faf280 100644 --- a/gdb/python/py-evts.c +++ b/gdb/python/py-evts.c @@ -62,46 +62,11 @@ gdbpy_initialize_py_events (void) if (!gdb_py_events.module) return -1; - if (add_new_registry (&gdb_py_events.stop, "stop") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.cont, "cont") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.exited, "exited") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.inferior_call, - "inferior_call") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.memory_changed, - "memory_changed") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.register_changed, - "register_changed") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.new_objfile, "new_objfile") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.clear_objfiles, "clear_objfiles") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.breakpoint_created, - "breakpoint_created") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.breakpoint_deleted, - "breakpoint_deleted") < 0) - return -1; - if (add_new_registry (&gdb_py_events.breakpoint_modified, - "breakpoint_modified") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.before_prompt, "before_prompt") < 0) +#define GDB_PY_DEFINE_EVENT(name) \ + if (add_new_registry (&gdb_py_events.name, #name) < 0) \ return -1; +#include "py-all-events.def" +#undef GDB_PY_DEFINE_EVENT if (gdb_pymodule_addobject (gdb_module, "events", diff --git a/gdb/python/py-exitedevent.c b/gdb/python/py-exitedevent.c index 967fb1b..aa4aefb 100644 --- a/gdb/python/py-exitedevent.c +++ b/gdb/python/py-exitedevent.c @@ -20,9 +20,6 @@ #include "defs.h" #include "py-event.h" -extern PyTypeObject exited_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - static PyObject * create_exited_event_object (const LONGEST *exit_code, struct inferior *inf) { @@ -67,10 +64,3 @@ emit_exited_event (const LONGEST *exit_code, struct inferior *inf) return -1; } - - -GDBPY_NEW_EVENT_TYPE (exited, - "gdb.ExitedEvent", - "ExitedEvent", - "GDB exited event object", - event_object_type); diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index 891f44e..a927b3c 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -119,7 +119,7 @@ static PyObject * frapy_name (PyObject *self, PyObject *args) { struct frame_info *frame; - char *name = NULL; + gdb::unique_xmalloc_ptr<char> name; enum language lang; PyObject *result; @@ -127,19 +127,18 @@ frapy_name (PyObject *self, PyObject *args) { FRAPY_REQUIRE_VALID (self, frame); - find_frame_funname (frame, &name, &lang, NULL); + name = find_frame_funname (frame, &lang, NULL); } CATCH (except, RETURN_MASK_ALL) { - xfree (name); GDB_PY_HANDLE_EXCEPTION (except); } END_CATCH if (name) { - result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL); - xfree (name); + result = PyUnicode_Decode (name.get (), strlen (name.get ()), + host_charset (), NULL); } else { @@ -334,13 +333,12 @@ frapy_function (PyObject *self, PyObject *args) TRY { - char *funname; enum language funlang; FRAPY_REQUIRE_VALID (self, frame); - find_frame_funname (frame, &funname, &funlang, &sym); - xfree (funname); + gdb::unique_xmalloc_ptr<char> funname + = find_frame_funname (frame, &funlang, &sym); } CATCH (except, RETURN_MASK_ALL) { @@ -468,14 +466,13 @@ static PyObject * frapy_find_sal (PyObject *self, PyObject *args) { struct frame_info *frame; - struct symtab_and_line sal; PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */ TRY { FRAPY_REQUIRE_VALID (self, frame); - find_frame_sal (frame, &sal); + symtab_and_line sal = find_frame_sal (frame); sal_obj = symtab_and_line_to_sal_object (sal); } CATCH (except, RETURN_MASK_ALL) diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index f6a24a0..381586d 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -235,6 +235,60 @@ inferior_to_inferior_object (struct inferior *inferior) return (PyObject *) inf_obj; } +/* Called when a new inferior is created. Notifies any Python event + listeners. */ +static void +python_new_inferior (struct inferior *inf) +{ + if (!gdb_python_initialized) + return; + + gdbpy_enter enter_py (python_gdbarch, python_language); + + if (evregpy_no_listeners_p (gdb_py_events.new_inferior)) + return; + + gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf)); + if (inf_obj == NULL) + { + gdbpy_print_stack (); + return; + } + + gdbpy_ref<> event (create_event_object (&new_inferior_event_object_type)); + if (event == NULL + || evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0 + || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0) + gdbpy_print_stack (); +} + +/* Called when an inferior is removed. Notifies any Python event + listeners. */ +static void +python_inferior_deleted (struct inferior *inf) +{ + if (!gdb_python_initialized) + return; + + gdbpy_enter enter_py (python_gdbarch, python_language); + + if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted)) + return; + + gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf)); + if (inf_obj == NULL) + { + gdbpy_print_stack (); + return; + } + + gdbpy_ref<> event (create_event_object (&inferior_deleted_event_object_type)); + if (event == NULL + || evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0 + || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0) + gdbpy_print_stack (); +} + /* Finds the Python Inferior object for the given PID. Returns a reference, or NULL if PID does not match any inferior object. */ @@ -298,6 +352,15 @@ add_thread_object (struct thread_info *tp) inf_obj->threads = entry; inf_obj->nthreads++; + + if (evregpy_no_listeners_p (gdb_py_events.new_thread)) + return; + + gdbpy_ref<> event (create_thread_event_object (&new_thread_event_object_type, + (PyObject *) thread_obj)); + if (event == NULL + || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0) + gdbpy_print_stack (); } static void @@ -751,6 +814,56 @@ infpy_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } +/* Implementation of gdb.Inferior.thread_from_thread_handle (self, handle) + -> gdb.InferiorThread. */ + +PyObject * +infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *handle_obj, *result; + inferior_object *inf_obj = (inferior_object *) self; + static const char *keywords[] = { "thread_handle", NULL }; + + INFPY_REQUIRE_VALID (inf_obj); + + if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj)) + return NULL; + + result = Py_None; + + if (!gdbpy_is_value_object (handle_obj)) + { + PyErr_SetString (PyExc_TypeError, + _("Argument 'handle_obj' must be a thread handle object.")); + + return NULL; + } + else + { + TRY + { + struct thread_info *thread_info; + struct value *val = value_object_to_value (handle_obj); + + thread_info = find_thread_by_handle (val, inf_obj->inferior); + if (thread_info != NULL) + { + result = (PyObject *) find_thread_object (thread_info->ptid); + if (result != NULL) + Py_INCREF (result); + } + } + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH + } + + return result; +} + + static void infpy_dealloc (PyObject *obj) { @@ -823,6 +936,8 @@ gdbpy_initialize_inferior (void) observer_attach_register_changed (python_on_register_change); observer_attach_inferior_exit (python_inferior_exit); observer_attach_new_objfile (python_new_objfile); + observer_attach_inferior_added (python_new_inferior); + observer_attach_inferior_removed (python_inferior_deleted); membuf_object_type.tp_new = PyType_GenericNew; if (PyType_Ready (&membuf_object_type) < 0) @@ -861,6 +976,10 @@ Write the given buffer object to the inferior's memory." }, METH_VARARGS | METH_KEYWORDS, "search_memory (address, length, pattern) -> long\n\ Return a long with the address of a match, or None." }, + { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle, + METH_VARARGS | METH_KEYWORDS, + "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\ +Return thread object corresponding to thread handle." }, { NULL } }; diff --git a/gdb/python/py-infevents.c b/gdb/python/py-infevents.c index 6e3c8c8..825a892 100644 --- a/gdb/python/py-infevents.c +++ b/gdb/python/py-infevents.c @@ -21,15 +21,6 @@ #include "py-event.h" #include "py-ref.h" -extern PyTypeObject inferior_call_pre_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject inferior_call_post_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject register_changed_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject memory_changed_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - /* Construct either a gdb.InferiorCallPreEvent or a gdb.InferiorCallPostEvent. */ @@ -43,10 +34,10 @@ create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid, switch (flag) { case INFERIOR_CALL_PRE: - event.reset (create_event_object (&inferior_call_pre_event_object_type)); + event = create_event_object (&inferior_call_pre_event_object_type); break; case INFERIOR_CALL_POST: - event.reset (create_event_object (&inferior_call_post_event_object_type)); + event = create_event_object (&inferior_call_post_event_object_type); break; default: gdb_assert_not_reached ("invalid inferior_call_kind"); @@ -172,28 +163,3 @@ emit_register_changed_event (struct frame_info* frame, int regnum) return evpy_emit_event (event.get (), gdb_py_events.register_changed); return -1; } - - -GDBPY_NEW_EVENT_TYPE (inferior_call_pre, - "gdb.InferiorCallPreEvent", - "InferiorCallPreEvent", - "GDB inferior function pre-call event object", - event_object_type); - -GDBPY_NEW_EVENT_TYPE (inferior_call_post, - "gdb.InferiorCallPostEvent", - "InferiorCallPostEvent", - "GDB inferior function post-call event object", - event_object_type); - -GDBPY_NEW_EVENT_TYPE (register_changed, - "gdb.RegisterChangedEvent", - "RegisterChangedEvent", - "GDB register change event object", - event_object_type); - -GDBPY_NEW_EVENT_TYPE (memory_changed, - "gdb.MemoryChangedEvent", - "MemoryChangedEvent", - "GDB memory change event object", - event_object_type); diff --git a/gdb/python/py-newobjfileevent.c b/gdb/python/py-newobjfileevent.c index dc09e0f..227f4a4 100644 --- a/gdb/python/py-newobjfileevent.c +++ b/gdb/python/py-newobjfileevent.c @@ -20,11 +20,6 @@ #include "defs.h" #include "py-event.h" -extern PyTypeObject new_objfile_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject clear_objfiles_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - static PyObject * create_new_objfile_event_object (struct objfile *objfile) { @@ -62,11 +57,6 @@ emit_new_objfile_event (struct objfile *objfile) return -1; } -GDBPY_NEW_EVENT_TYPE (new_objfile, - "gdb.NewObjFileEvent", - "NewObjFileEvent", - "GDB new object file event object", - event_object_type); /* Subroutine of emit_clear_objfiles_event to simplify it. */ @@ -107,9 +97,3 @@ emit_clear_objfiles_event (void) return evpy_emit_event (event.get (), gdb_py_events.clear_objfiles); return -1; } - -GDBPY_NEW_EVENT_TYPE (clear_objfiles, - "gdb.ClearObjFilesEvent", - "ClearObjFilesEvent", - "GDB clear object files event object", - event_object_type); diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c index f0d3423..455c99e 100644 --- a/gdb/python/py-param.c +++ b/gdb/python/py-param.c @@ -555,7 +555,6 @@ static int compute_enum_values (parmpy_object *self, PyObject *enum_values) { Py_ssize_t size, i; - struct cleanup *back_to; if (! enum_values) { @@ -581,36 +580,27 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values) return 0; } - self->enumeration = XCNEWVEC (const char *, size + 1); - back_to = make_cleanup (free_current_contents, &self->enumeration); + gdb_argv holder (XCNEWVEC (char *, size + 1)); + char **enumeration = holder.get (); for (i = 0; i < size; ++i) { gdbpy_ref<> item (PySequence_GetItem (enum_values, i)); if (item == NULL) - { - do_cleanups (back_to); - return 0; - } + return 0; if (! gdbpy_is_string (item.get ())) { - do_cleanups (back_to); PyErr_SetString (PyExc_RuntimeError, _("The enumeration item not a string.")); return 0; } - self->enumeration[i] - = python_string_to_host_string (item.get ()).release (); - if (self->enumeration[i] == NULL) - { - do_cleanups (back_to); - return 0; - } - make_cleanup (xfree, (char *) self->enumeration[i]); + enumeration[i] = python_string_to_host_string (item.get ()).release (); + if (enumeration[i] == NULL) + return 0; } - discard_cleanups (back_to); + self->enumeration = const_cast<const char**> (holder.release ()); return 1; } diff --git a/gdb/python/py-record-btrace.c b/gdb/python/py-record-btrace.c index cd2be9f..220990b 100644 --- a/gdb/python/py-record-btrace.c +++ b/gdb/python/py-record-btrace.c @@ -376,7 +376,7 @@ recpy_bt_func_instructions (PyObject *self, void *closure) if (func == NULL) return NULL; - len = VEC_length (btrace_insn_s, func->insn); + len = func->insn.size (); /* Gaps count as one instruction. */ if (len == 0) diff --git a/gdb/python/py-signalevent.c b/gdb/python/py-signalevent.c index a8f41c2..185e6f5 100644 --- a/gdb/python/py-signalevent.c +++ b/gdb/python/py-signalevent.c @@ -20,10 +20,7 @@ #include "defs.h" #include "py-stopevent.h" -extern PyTypeObject signal_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - -PyObject * +gdbpy_ref<> create_signal_event_object (enum gdb_signal stop_signal) { const char *signal_name; @@ -43,11 +40,5 @@ create_signal_event_object (enum gdb_signal stop_signal) signal_name_obj.get ()) < 0) return NULL; - return signal_event_obj.release (); + return signal_event_obj; } - -GDBPY_NEW_EVENT_TYPE (signal, - "gdb.SignalEvent", - "SignalEvent", - "GDB signal event object", - stop_event_object_type); diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c index cfa4591..5717947 100644 --- a/gdb/python/py-stopevent.c +++ b/gdb/python/py-stopevent.c @@ -20,7 +20,7 @@ #include "defs.h" #include "py-stopevent.h" -PyObject * +gdbpy_ref<> create_stop_event_object (PyTypeObject *py_type) { return create_thread_event_object (py_type); @@ -70,8 +70,8 @@ emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) if (list != NULL) { - stop_event_obj.reset (create_breakpoint_event_object (list.get (), - first_bp)); + stop_event_obj = create_breakpoint_event_object (list.get (), + first_bp); if (stop_event_obj == NULL) return -1; } @@ -80,7 +80,7 @@ emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) if (stop_signal != GDB_SIGNAL_0 && stop_signal != GDB_SIGNAL_TRAP) { - stop_event_obj.reset (create_signal_event_object (stop_signal)); + stop_event_obj = create_signal_event_object (stop_signal); if (stop_event_obj == NULL) return -1; } @@ -89,16 +89,10 @@ emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) be known and this should eventually be unused. */ if (stop_event_obj == NULL) { - stop_event_obj.reset (create_stop_event_object (&stop_event_object_type)); + stop_event_obj = create_stop_event_object (&stop_event_object_type); if (stop_event_obj == NULL) return -1; } return evpy_emit_event (stop_event_obj.get (), gdb_py_events.stop); } - -GDBPY_NEW_EVENT_TYPE (stop, - "gdb.StopEvent", - "StopEvent", - "GDB stop event object", - thread_event_object_type); diff --git a/gdb/python/py-stopevent.h b/gdb/python/py-stopevent.h index a56ca7e..62c52d7 100644 --- a/gdb/python/py-stopevent.h +++ b/gdb/python/py-stopevent.h @@ -22,15 +22,15 @@ #include "py-event.h" -extern PyObject *create_stop_event_object (PyTypeObject *py_type); +extern gdbpy_ref<> create_stop_event_object (PyTypeObject *py_type); extern void stop_evpy_dealloc (PyObject *self); extern int emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal); -extern PyObject *create_breakpoint_event_object (PyObject *breakpoint_list, - PyObject *first_bp); +extern gdbpy_ref<> create_breakpoint_event_object (PyObject *breakpoint_list, + PyObject *first_bp); -extern PyObject *create_signal_event_object (enum gdb_signal stop_signal); +extern gdbpy_ref<> create_signal_event_object (enum gdb_signal stop_signal); #endif /* GDB_PY_STOPEVENT_H */ diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c index 9217444..322fa26 100644 --- a/gdb/python/py-threadevent.c +++ b/gdb/python/py-threadevent.c @@ -47,29 +47,24 @@ get_event_thread (void) return thread; } -PyObject * -create_thread_event_object (PyTypeObject *py_type) +gdbpy_ref<> +create_thread_event_object (PyTypeObject *py_type, PyObject *thread) { - PyObject *thread = NULL; - gdbpy_ref<> thread_event_obj (create_event_object (py_type)); if (thread_event_obj == NULL) return NULL; - thread = get_event_thread (); - if (!thread) - return NULL; + if (thread == NULL) + { + thread = get_event_thread (); + if (!thread) + return NULL; + } if (evpy_add_attribute (thread_event_obj.get (), "inferior_thread", thread) < 0) return NULL; - return thread_event_obj.release (); + return thread_event_obj; } - -GDBPY_NEW_EVENT_TYPE (thread, - "gdb.ThreadEvent", - "ThreadEvent", - "GDB thread event object", - event_object_type); diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index aa20d4c..51184ca 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -761,7 +761,6 @@ typy_lookup_type (struct demangle_component *demangled, const struct block *block) { struct type *type, *rtype = NULL; - char *type_name = NULL; enum demangle_component_type demangled_type; /* Save the type: typy_lookup_type() may (indirectly) overwrite @@ -816,11 +815,8 @@ typy_lookup_type (struct demangle_component *demangled, return rtype; /* We don't have a type, so lookup the type. */ - type_name = cp_comp_to_string (demangled, 10); - type = typy_lookup_typename (type_name, block); - xfree (type_name); - - return type; + gdb::unique_xmalloc_ptr<char> type_name = cp_comp_to_string (demangled, 10); + return typy_lookup_typename (type_name.get (), block); } /* This is a helper function for typy_template_argument that is used diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index 1d800a7..acfce7d 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -595,7 +595,7 @@ pyuw_dealloc_cache (struct frame_info *this_frame, void *cache) TRACE_PY_UNWIND (3, "%s: enter", __FUNCTION__); cached_frame_info *cached_frame = (cached_frame_info *) cache; - for (int i = 0; cached_frame->reg_count; i++) + for (int i = 0; i < cached_frame->reg_count; i++) xfree (cached_frame->reg[i].data); xfree (cache); diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index b5a0ef8..cbbb936 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -925,7 +925,8 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) scoped_value_mark free_values; struct value *return_value; - return_value = call_function_by_hand (function, args_count, vargs); + return_value = call_function_by_hand (function, NULL, + args_count, vargs); result = value_to_value_object (return_value); } CATCH (except, RETURN_MASK_ALL) diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c index e858556..5f6ab64 100644 --- a/gdb/python/py-varobj.c +++ b/gdb/python/py-varobj.c @@ -71,7 +71,6 @@ py_varobj_iter_next (struct varobj_iter *self) if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) { PyObject *type, *value, *trace; - char *name_str; PyErr_Fetch (&type, &value, &trace); gdb::unique_xmalloc_ptr<char> @@ -85,10 +84,10 @@ py_varobj_iter_next (struct varobj_iter *self) return NULL; } - name_str = xstrprintf ("<error at %d>", - self->next_raw_index++); - item.reset (Py_BuildValue ("(ss)", name_str, value_str.get ())); - xfree (name_str); + std::string name_str = string_printf ("<error at %d>", + self->next_raw_index++); + item.reset (Py_BuildValue ("(ss)", name_str.c_str (), + value_str.get ())); if (item == NULL) { gdbpy_print_stack (); diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index ebb83f0..8fc8cc5 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -373,12 +373,12 @@ extern PyTypeObject symbol_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symbol_object"); extern PyTypeObject event_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject stop_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); extern PyTypeObject breakpoint_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("breakpoint_object"); extern PyTypeObject frame_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("frame_object"); +extern PyTypeObject thread_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("thread_object"); typedef struct gdbpy_breakpoint_object { @@ -606,30 +606,6 @@ int gdbpy_initialize_event (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_py_events (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_stop_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_signal_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_breakpoint_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_continue_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_inferior_call_pre_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_inferior_call_post_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_register_changed_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_memory_changed_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_exited_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_thread_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_new_objfile_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_clear_objfiles_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_arch (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_xmethods (void) @@ -650,8 +626,7 @@ class gdbpy_enter ~gdbpy_enter (); - gdbpy_enter (const gdbpy_enter &) = delete; - gdbpy_enter &operator= (const gdbpy_enter &) = delete; + DISABLE_COPY_AND_ASSIGN (gdbpy_enter); private: diff --git a/gdb/python/python.c b/gdb/python/python.c index be92f36..ff757fd 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -365,32 +365,19 @@ python_run_simple_file (FILE *file, const char *filename) } /* Given a command_line, return a command string suitable for passing - to Python. Lines in the string are separated by newlines. The - return value is allocated using xmalloc and the caller is - responsible for freeing it. */ + to Python. Lines in the string are separated by newlines. */ -static char * +static std::string compute_python_string (struct command_line *l) { struct command_line *iter; - char *script = NULL; - int size = 0; - int here; + std::string script; for (iter = l; iter; iter = iter->next) - size += strlen (iter->line) + 1; - - script = (char *) xmalloc (size + 1); - here = 0; - for (iter = l; iter; iter = iter->next) { - int len = strlen (iter->line); - - strcpy (&script[here], iter->line); - here += len; - script[here++] = '\n'; + script += iter->line; + script += '\n'; } - script[here] = '\0'; return script; } @@ -402,16 +389,14 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang, struct command_line *cmd) { int ret; - char *script; if (cmd->body_count != 1) error (_("Invalid \"python\" block structure.")); gdbpy_enter enter_py (get_current_arch (), current_language); - script = compute_python_string (cmd->body_list[0]); - ret = PyRun_SimpleString (script); - xfree (script); + std::string script = compute_python_string (cmd->body_list[0]); + ret = PyRun_SimpleString (script.c_str ()); if (ret) error (_("Error while executing Python code.")); } @@ -662,12 +647,7 @@ gdbpy_solib_name (PyObject *self, PyObject *args) static PyObject * gdbpy_decode_line (PyObject *self, PyObject *args) { - struct gdb_exception except = exception_none; - struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to - appease gcc. */ - struct symtab_and_line sal; char *arg = NULL; - struct cleanup *cleanups; gdbpy_ref<> result; gdbpy_ref<> unparsed; event_location_up location; @@ -675,62 +655,44 @@ gdbpy_decode_line (PyObject *self, PyObject *args) if (! PyArg_ParseTuple (args, "|s", &arg)) return NULL; - cleanups = make_cleanup (null_cleanup, NULL); - - sals.sals = NULL; - if (arg != NULL) location = string_to_event_location_basic (&arg, python_language); + std::vector<symtab_and_line> decoded_sals; + symtab_and_line def_sal; + gdb::array_view<symtab_and_line> sals; TRY { if (location != NULL) - sals = decode_line_1 (location.get (), 0, NULL, NULL, 0); + { + decoded_sals = decode_line_1 (location.get (), 0, NULL, NULL, 0); + sals = decoded_sals; + } else { set_default_source_symtab_and_line (); - sal = get_current_source_symtab_and_line (); - sals.sals = &sal; - sals.nelts = 1; + def_sal = get_current_source_symtab_and_line (); + sals = def_sal; } } CATCH (ex, RETURN_MASK_ALL) { - except = ex; - } - END_CATCH - - if (sals.sals != NULL && sals.sals != &sal) - make_cleanup (xfree, sals.sals); - - if (except.reason < 0) - { - do_cleanups (cleanups); /* We know this will always throw. */ - gdbpy_convert_exception (except); + gdbpy_convert_exception (ex); return NULL; } + END_CATCH - if (sals.nelts) + if (!sals.empty ()) { - int i; - - result.reset (PyTuple_New (sals.nelts)); + result.reset (PyTuple_New (sals.size ())); if (result == NULL) + return NULL; + for (size_t i = 0; i < sals.size (); ++i) { - do_cleanups (cleanups); - return NULL; - } - for (i = 0; i < sals.nelts; ++i) - { - PyObject *obj; - - obj = symtab_and_line_to_sal_object (sals.sals[i]); - if (! obj) - { - do_cleanups (cleanups); - return NULL; - } + PyObject *obj = symtab_and_line_to_sal_object (sals[i]); + if (obj == NULL) + return NULL; PyTuple_SetItem (result.get (), i, obj); } @@ -743,19 +705,13 @@ gdbpy_decode_line (PyObject *self, PyObject *args) gdbpy_ref<> return_result (PyTuple_New (2)); if (return_result == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; if (arg != NULL && strlen (arg) > 0) { unparsed.reset (PyString_FromString (arg)); if (unparsed == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; } else { @@ -766,8 +722,6 @@ gdbpy_decode_line (PyObject *self, PyObject *args) PyTuple_SetItem (return_result.get (), 0, unparsed.release ()); PyTuple_SetItem (return_result.get (), 1, result.release ()); - do_cleanups (cleanups); - return return_result.release (); } @@ -1518,12 +1472,6 @@ finalize_python (void *ignore) restore_active_ext_lang (previous_active); } -#endif - -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_python; - -#ifdef HAVE_PYTHON static bool do_start_initialization () @@ -1532,7 +1480,6 @@ do_start_initialization () #ifdef IS_PY3K int i; size_t progsize, count; - char *oldloc; wchar_t *progname_copy; #endif @@ -1546,25 +1493,22 @@ do_start_initialization () progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin", SLASH_STRING, "python", (char *) NULL); #ifdef IS_PY3K - oldloc = xstrdup (setlocale (LC_ALL, NULL)); + std::string oldloc = setlocale (LC_ALL, NULL); setlocale (LC_ALL, ""); progsize = strlen (progname); progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t)); if (!progname_copy) { - xfree (oldloc); fprintf (stderr, "out of memory\n"); return false; } count = mbstowcs (progname_copy, progname, progsize + 1); if (count == (size_t) -1) { - xfree (oldloc); fprintf (stderr, "Could not convert python path to string\n"); return false; } - setlocale (LC_ALL, oldloc); - xfree (oldloc); + setlocale (LC_ALL, oldloc.c_str ()); /* Note that Py_SetProgramName expects the string it is passed to remain alive for the duration of the program's execution, so @@ -1647,23 +1591,17 @@ do_start_initialization () || gdbpy_initialize_eventregistry () < 0 || gdbpy_initialize_py_events () < 0 || gdbpy_initialize_event () < 0 - || gdbpy_initialize_stop_event () < 0 - || gdbpy_initialize_signal_event () < 0 - || gdbpy_initialize_breakpoint_event () < 0 - || gdbpy_initialize_continue_event () < 0 - || gdbpy_initialize_inferior_call_pre_event () < 0 - || gdbpy_initialize_inferior_call_post_event () < 0 - || gdbpy_initialize_register_changed_event () < 0 - || gdbpy_initialize_memory_changed_event () < 0 - || gdbpy_initialize_exited_event () < 0 - || gdbpy_initialize_thread_event () < 0 - || gdbpy_initialize_new_objfile_event () < 0 - || gdbpy_initialize_clear_objfiles_event () < 0 || gdbpy_initialize_arch () < 0 || gdbpy_initialize_xmethods () < 0 || gdbpy_initialize_unwind () < 0) return false; +#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \ + if (gdbpy_initialize_event_generic (&name##_event_object_type, py_name) < 0) \ + return false; +#include "py-event-types.def" +#undef GDB_PY_DEFINE_EVENT_TYPE + gdbpy_to_string_cst = PyString_FromString ("to_string"); if (gdbpy_to_string_cst == NULL) return false; @@ -2016,4 +1954,51 @@ struct PyModuleDef python_GdbModuleDef = NULL }; #endif + +/* Define all the event objects. */ +#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \ + PyTypeObject name##_event_object_type \ + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object") \ + = { \ + PyVarObject_HEAD_INIT (NULL, 0) \ + "gdb." py_name, /* tp_name */ \ + sizeof (event_object), /* tp_basicsize */ \ + 0, /* tp_itemsize */ \ + evpy_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_BASETYPE, /* tp_flags */ \ + doc, /* 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 */ \ + 0, /* tp_getset */ \ + &base, /* tp_base */ \ + 0, /* tp_dict */ \ + 0, /* tp_descr_get */ \ + 0, /* tp_descr_set */ \ + 0, /* tp_dictoffset */ \ + 0, /* tp_init */ \ + 0 /* tp_alloc */ \ + }; +#include "py-event-types.def" +#undef GDB_PY_DEFINE_EVENT_TYPE + #endif /* HAVE_PYTHON */ |