gdb/python/py-infevents.c - gdb

Functions defined

Source code

  1. /* Python interface to inferior function events.

  2.    Copyright (C) 2013-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "py-event.h"

  16. static PyTypeObject inferior_call_pre_event_object_type
  17.     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
  18. static PyTypeObject inferior_call_post_event_object_type
  19.     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
  20. static PyTypeObject register_changed_event_object_type
  21.     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
  22. static PyTypeObject memory_changed_event_object_type
  23.     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");

  24. /* Construct either a gdb.InferiorCallPreEvent or a
  25.    gdb.InferiorCallPostEvent. */

  26. static PyObject *
  27. create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid,
  28.                                    CORE_ADDR addr)
  29. {
  30.   int pid;
  31.   long tid, lwp;
  32.   PyObject *event;
  33.   PyObject *ptid_obj = NULL;
  34.   PyObject *addr_obj = NULL;
  35.   int failed;
  36.   struct cleanup *cleanups;
  37.   struct cleanup *member_cleanups;

  38.   switch (flag)
  39.     {
  40.     case INFERIOR_CALL_PRE:
  41.       event = create_event_object (&inferior_call_pre_event_object_type);
  42.       break;
  43.     case INFERIOR_CALL_POST:
  44.       event = create_event_object (&inferior_call_post_event_object_type);
  45.       break;
  46.     default:
  47.       return NULL;
  48.     }

  49.   cleanups = make_cleanup_py_decref (event);

  50.   ptid_obj = gdbpy_create_ptid_object (ptid);
  51.   if (ptid_obj == NULL)
  52.     goto fail;
  53.   member_cleanups = make_cleanup_py_decref (ptid_obj);

  54.   failed = evpy_add_attribute (event, "ptid", ptid_obj) < 0;
  55.   if (failed)
  56.     goto fail;

  57.   addr_obj = PyLong_FromLongLong (addr);
  58.   if (addr_obj == NULL)
  59.     goto fail;
  60.   make_cleanup_py_decref (addr_obj);

  61.   failed = evpy_add_attribute (event, "address", addr_obj) < 0;
  62.   if (failed)
  63.     goto fail;

  64.   do_cleanups (member_cleanups);
  65.   discard_cleanups (cleanups);
  66.   return event;

  67. fail:
  68.   do_cleanups (cleanups);
  69.   return NULL;
  70. }

  71. /* Construct a gdb.RegisterChangedEvent containing the affected
  72.    register number. */

  73. static PyObject *
  74. create_register_changed_event_object (struct frame_info *frame,
  75.                                       int regnum)
  76. {
  77.   PyObject *event;
  78.   PyObject *frame_obj = NULL;
  79.   PyObject *regnum_obj = NULL;
  80.   int failed;
  81.   struct cleanup *cleanups;
  82.   struct cleanup *member_cleanups;

  83.   event = create_event_object (&register_changed_event_object_type);
  84.   if (event == NULL)
  85.     return NULL;

  86.   cleanups = make_cleanup_py_decref (event);

  87.   frame_obj = frame_info_to_frame_object (frame);
  88.   if (frame_obj == NULL)
  89.     goto fail;
  90.   member_cleanups = make_cleanup_py_decref (frame_obj);

  91.   failed = evpy_add_attribute (event, "frame", frame_obj) < 0;
  92.   if (failed)
  93.     goto fail;

  94.   regnum_obj = PyLong_FromLongLong (regnum);
  95.   if (regnum_obj == NULL)
  96.     goto fail;
  97.   make_cleanup_py_decref (regnum_obj);

  98.   failed = evpy_add_attribute (event, "regnum", regnum_obj) < 0;
  99.   if (failed)
  100.     goto fail;

  101.   do_cleanups (member_cleanups);
  102.   discard_cleanups (cleanups);
  103.   return event;

  104. fail:
  105.   do_cleanups (cleanups);
  106.   return NULL;
  107. }

  108. /* Construct a gdb.MemoryChangedEvent describing the extent of the
  109.    affected memory. */

  110. static PyObject *
  111. create_memory_changed_event_object (CORE_ADDR addr, ssize_t len)
  112. {
  113.   PyObject *event;
  114.   PyObject *addr_obj = NULL;
  115.   PyObject *len_obj = NULL;
  116.   int failed;
  117.   struct cleanup *cleanups;
  118.   struct cleanup *member_cleanups;

  119.   event = create_event_object (&memory_changed_event_object_type);

  120.   if (event == NULL)
  121.     return NULL;
  122.   cleanups = make_cleanup_py_decref (event);

  123.   addr_obj = PyLong_FromLongLong (addr);
  124.   if (addr_obj == NULL)
  125.     goto fail;
  126.   member_cleanups = make_cleanup_py_decref (addr_obj);

  127.   failed = evpy_add_attribute (event, "address", addr_obj) < 0;
  128.   if (failed)
  129.     goto fail;

  130.   len_obj = PyLong_FromLong (len);
  131.   if (len_obj == NULL)
  132.     goto fail;
  133.   make_cleanup_py_decref (len_obj);

  134.   failed = evpy_add_attribute (event, "length", len_obj) < 0;
  135.   if (failed)
  136.     goto fail;

  137.   do_cleanups (member_cleanups);
  138.   discard_cleanups (cleanups);
  139.   return event;

  140. fail:
  141.   do_cleanups (cleanups);
  142.   return NULL;
  143. }

  144. /* Callback function which notifies observers when an event occurs which
  145.    calls a function in the inferior.
  146.    This function will create a new Python inferior-call event object.
  147.    Return -1 if emit fails.  */

  148. int
  149. emit_inferior_call_event (inferior_call_kind flag, ptid_t thread,
  150.                           CORE_ADDR addr)
  151. {
  152.   PyObject *event;

  153.   if (evregpy_no_listeners_p (gdb_py_events.inferior_call))
  154.     return 0;

  155.   event = create_inferior_call_event_object (flag, thread, addr);
  156.   if (event != NULL)
  157.     return evpy_emit_event (event, gdb_py_events.inferior_call);
  158.   return -1;
  159. }

  160. /* Callback when memory is modified by the user.  This function will
  161.    create a new Python memory changed event object. */

  162. int
  163. emit_memory_changed_event (CORE_ADDR addr, ssize_t len)
  164. {
  165.   PyObject *event;

  166.   if (evregpy_no_listeners_p (gdb_py_events.memory_changed))
  167.     return 0;

  168.   event = create_memory_changed_event_object (addr, len);
  169.   if (event != NULL)
  170.     return evpy_emit_event (event, gdb_py_events.memory_changed);
  171.   return -1;
  172. }

  173. /* Callback when a register is modified by the user.  This function
  174.    will create a new Python register changed event object. */

  175. int
  176. emit_register_changed_event (struct frame_info* frame, int regnum)
  177. {
  178.   PyObject *event;

  179.   if (evregpy_no_listeners_p (gdb_py_events.register_changed))
  180.     return 0;

  181.   event = create_register_changed_event_object (frame, regnum);
  182.   if (event != NULL)
  183.     return evpy_emit_event (event, gdb_py_events.register_changed);
  184.   return -1;
  185. }


  186. GDBPY_NEW_EVENT_TYPE (inferior_call_pre,
  187.                       "gdb.InferiorCallPreEvent",
  188.                       "InferiorCallPreEvent",
  189.                       "GDB inferior function pre-call event object",
  190.                       event_object_type,
  191.                       static);

  192. GDBPY_NEW_EVENT_TYPE (inferior_call_post,
  193.                       "gdb.InferiorCallPostEvent",
  194.                       "InferiorCallPostEvent",
  195.                       "GDB inferior function post-call event object",
  196.                       event_object_type,
  197.                       static);

  198. GDBPY_NEW_EVENT_TYPE (register_changed,
  199.                       "gdb.RegisterChangedEvent",
  200.                       "RegisterChangedEvent",
  201.                       "GDB register change event object",
  202.                       event_object_type,
  203.                       static);

  204. GDBPY_NEW_EVENT_TYPE (memory_changed,
  205.                       "gdb.MemoryChangedEvent",
  206.                       "MemoryChangedEvent",
  207.                       "GDB memory change event object",
  208.                       event_object_type,
  209.                       static);