1c50c785cSJohn Marino /* Python interface to inferior stop events.
2c50c785cSJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2009-2013 Free Software Foundation, Inc.
4c50c785cSJohn Marino
5c50c785cSJohn Marino This file is part of GDB.
6c50c785cSJohn Marino
7c50c785cSJohn Marino This program is free software; you can redistribute it and/or modify
8c50c785cSJohn Marino it under the terms of the GNU General Public License as published by
9c50c785cSJohn Marino the Free Software Foundation; either version 3 of the License, or
10c50c785cSJohn Marino (at your option) any later version.
11c50c785cSJohn Marino
12c50c785cSJohn Marino This program is distributed in the hope that it will be useful,
13c50c785cSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14c50c785cSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15c50c785cSJohn Marino GNU General Public License for more details.
16c50c785cSJohn Marino
17c50c785cSJohn Marino You should have received a copy of the GNU General Public License
18c50c785cSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19c50c785cSJohn Marino
20*ef5ccd6cSJohn Marino #include "defs.h"
21c50c785cSJohn Marino #include "py-stopevent.h"
22c50c785cSJohn Marino
23c50c785cSJohn Marino PyObject *
create_stop_event_object(PyTypeObject * py_type)24c50c785cSJohn Marino create_stop_event_object (PyTypeObject *py_type)
25c50c785cSJohn Marino {
26c50c785cSJohn Marino PyObject *stop_event_obj = create_thread_event_object (py_type);
27c50c785cSJohn Marino
28c50c785cSJohn Marino if (!stop_event_obj)
29c50c785cSJohn Marino goto fail;
30c50c785cSJohn Marino
31c50c785cSJohn Marino return stop_event_obj;
32c50c785cSJohn Marino
33c50c785cSJohn Marino fail:
34c50c785cSJohn Marino Py_XDECREF (stop_event_obj);
35c50c785cSJohn Marino return NULL;
36c50c785cSJohn Marino }
37c50c785cSJohn Marino
38c50c785cSJohn Marino /* Callback observers when a stop event occurs. This function will create a
39c50c785cSJohn Marino new Python stop event object. If only a specific thread is stopped the
40c50c785cSJohn Marino thread object of the event will be set to that thread. Otherwise, if all
41c50c785cSJohn Marino threads are stopped thread object will be set to None.
42c50c785cSJohn Marino return 0 if the event was created and emitted successfully otherwise
43c50c785cSJohn Marino returns -1. */
44c50c785cSJohn Marino
45c50c785cSJohn Marino int
emit_stop_event(struct bpstats * bs,enum gdb_signal stop_signal)46*ef5ccd6cSJohn Marino emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal)
47c50c785cSJohn Marino {
48c50c785cSJohn Marino PyObject *stop_event_obj = NULL; /* Appease GCC warning. */
49a45ae5f8SJohn Marino PyObject *list = NULL;
50a45ae5f8SJohn Marino PyObject *first_bp = NULL;
51a45ae5f8SJohn Marino struct bpstats *current_bs;
52c50c785cSJohn Marino
53c50c785cSJohn Marino if (evregpy_no_listeners_p (gdb_py_events.stop))
54c50c785cSJohn Marino return 0;
55c50c785cSJohn Marino
56a45ae5f8SJohn Marino /* Add any breakpoint set at this location to the list. */
57a45ae5f8SJohn Marino for (current_bs = bs; current_bs != NULL; current_bs = current_bs->next)
58c50c785cSJohn Marino {
59a45ae5f8SJohn Marino if (current_bs->breakpoint_at
60a45ae5f8SJohn Marino && current_bs->breakpoint_at->py_bp_object)
61a45ae5f8SJohn Marino {
62a45ae5f8SJohn Marino PyObject *current_py_bp =
63a45ae5f8SJohn Marino (PyObject *) current_bs->breakpoint_at->py_bp_object;
64a45ae5f8SJohn Marino
65a45ae5f8SJohn Marino if (list == NULL)
66a45ae5f8SJohn Marino {
67a45ae5f8SJohn Marino list = PyList_New (0);
68a45ae5f8SJohn Marino if (!list)
69a45ae5f8SJohn Marino goto fail;
70a45ae5f8SJohn Marino }
71a45ae5f8SJohn Marino
72a45ae5f8SJohn Marino if (PyList_Append (list, current_py_bp))
73a45ae5f8SJohn Marino goto fail;
74a45ae5f8SJohn Marino
75a45ae5f8SJohn Marino if (first_bp == NULL)
76a45ae5f8SJohn Marino first_bp = current_py_bp;
77a45ae5f8SJohn Marino }
78a45ae5f8SJohn Marino }
79a45ae5f8SJohn Marino
80a45ae5f8SJohn Marino if (list != NULL)
81a45ae5f8SJohn Marino {
82a45ae5f8SJohn Marino stop_event_obj = create_breakpoint_event_object (list, first_bp);
83c50c785cSJohn Marino if (!stop_event_obj)
84c50c785cSJohn Marino goto fail;
85*ef5ccd6cSJohn Marino Py_DECREF (list);
86c50c785cSJohn Marino }
87c50c785cSJohn Marino
88c50c785cSJohn Marino /* Check if the signal is "Signal 0" or "Trace/breakpoint trap". */
89*ef5ccd6cSJohn Marino if (stop_signal != GDB_SIGNAL_0
90*ef5ccd6cSJohn Marino && stop_signal != GDB_SIGNAL_TRAP)
91c50c785cSJohn Marino {
92c50c785cSJohn Marino stop_event_obj =
93c50c785cSJohn Marino create_signal_event_object (stop_signal);
94c50c785cSJohn Marino if (!stop_event_obj)
95c50c785cSJohn Marino goto fail;
96c50c785cSJohn Marino }
97c50c785cSJohn Marino
98c50c785cSJohn Marino /* If all fails emit an unknown stop event. All event types should
99c50c785cSJohn Marino be known and this should eventually be unused. */
100c50c785cSJohn Marino if (!stop_event_obj)
101c50c785cSJohn Marino {
102c50c785cSJohn Marino stop_event_obj = create_stop_event_object (&stop_event_object_type);
103c50c785cSJohn Marino if (!stop_event_obj)
104c50c785cSJohn Marino goto fail;
105c50c785cSJohn Marino }
106c50c785cSJohn Marino
107c50c785cSJohn Marino return evpy_emit_event (stop_event_obj, gdb_py_events.stop);
108c50c785cSJohn Marino
109c50c785cSJohn Marino fail:
110a45ae5f8SJohn Marino Py_XDECREF (list);
111c50c785cSJohn Marino return -1;
112c50c785cSJohn Marino }
113c50c785cSJohn Marino
114c50c785cSJohn Marino GDBPY_NEW_EVENT_TYPE (stop,
115c50c785cSJohn Marino "gdb.StopEvent",
116c50c785cSJohn Marino "StopEvent",
117c50c785cSJohn Marino "GDB stop event object",
118c50c785cSJohn Marino thread_event_object_type,
119c50c785cSJohn Marino /*no qual*/);
120