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