GDB (API)
|
00001 /* Python interface to inferior stop events. 00002 00003 Copyright (C) 2009-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "py-stopevent.h" 00022 00023 PyObject * 00024 create_stop_event_object (PyTypeObject *py_type) 00025 { 00026 PyObject *stop_event_obj = create_thread_event_object (py_type); 00027 00028 if (!stop_event_obj) 00029 goto fail; 00030 00031 return stop_event_obj; 00032 00033 fail: 00034 Py_XDECREF (stop_event_obj); 00035 return NULL; 00036 } 00037 00038 /* Callback observers when a stop event occurs. This function will create a 00039 new Python stop event object. If only a specific thread is stopped the 00040 thread object of the event will be set to that thread. Otherwise, if all 00041 threads are stopped thread object will be set to None. 00042 return 0 if the event was created and emitted successfully otherwise 00043 returns -1. */ 00044 00045 int 00046 emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) 00047 { 00048 PyObject *stop_event_obj = NULL; /* Appease GCC warning. */ 00049 PyObject *list = NULL; 00050 PyObject *first_bp = NULL; 00051 struct bpstats *current_bs; 00052 00053 if (evregpy_no_listeners_p (gdb_py_events.stop)) 00054 return 0; 00055 00056 /* Add any breakpoint set at this location to the list. */ 00057 for (current_bs = bs; current_bs != NULL; current_bs = current_bs->next) 00058 { 00059 if (current_bs->breakpoint_at 00060 && current_bs->breakpoint_at->py_bp_object) 00061 { 00062 PyObject *current_py_bp = 00063 (PyObject *) current_bs->breakpoint_at->py_bp_object; 00064 00065 if (list == NULL) 00066 { 00067 list = PyList_New (0); 00068 if (!list) 00069 goto fail; 00070 } 00071 00072 if (PyList_Append (list, current_py_bp)) 00073 goto fail; 00074 00075 if (first_bp == NULL) 00076 first_bp = current_py_bp; 00077 } 00078 } 00079 00080 if (list != NULL) 00081 { 00082 stop_event_obj = create_breakpoint_event_object (list, first_bp); 00083 if (!stop_event_obj) 00084 goto fail; 00085 Py_DECREF (list); 00086 } 00087 00088 /* Check if the signal is "Signal 0" or "Trace/breakpoint trap". */ 00089 if (stop_signal != GDB_SIGNAL_0 00090 && stop_signal != GDB_SIGNAL_TRAP) 00091 { 00092 stop_event_obj = 00093 create_signal_event_object (stop_signal); 00094 if (!stop_event_obj) 00095 goto fail; 00096 } 00097 00098 /* If all fails emit an unknown stop event. All event types should 00099 be known and this should eventually be unused. */ 00100 if (!stop_event_obj) 00101 { 00102 stop_event_obj = create_stop_event_object (&stop_event_object_type); 00103 if (!stop_event_obj) 00104 goto fail; 00105 } 00106 00107 return evpy_emit_event (stop_event_obj, gdb_py_events.stop); 00108 00109 fail: 00110 Py_XDECREF (list); 00111 return -1; 00112 } 00113 00114 GDBPY_NEW_EVENT_TYPE (stop, 00115 "gdb.StopEvent", 00116 "StopEvent", 00117 "GDB stop event object", 00118 thread_event_object_type, 00119 /*no qual*/);