gdb.rb 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +7 -1
- data/bin/gdb.rb +4 -3
- data/ext/extconf.rb +1 -3
- data/ext/src/{gdb-7.0.tar.bz2 → gdb-7.2.tar.bz2} +0 -0
- data/gdb.rb.gemspec +5 -18
- data/patches/gdb-leak.patch +41 -61
- data/scripts/ruby-gdb.py +54 -27
- metadata +20 -10
- data/patches/gdb-breakpoints.patch +0 -744
- data/patches/gdb-eval.patch +0 -57
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gdb.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 17
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Aman Gupta
|
@@ -9,11 +15,11 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-11-04 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
16
|
-
description: A set of gdb7 extensions for the MRI interpreter
|
22
|
+
description: A set of gdb7 extensions for the MRI/REE 1.8.x interpreter
|
17
23
|
email: gdb@tmm1.net
|
18
24
|
executables:
|
19
25
|
- gdb.rb
|
@@ -26,10 +32,8 @@ files:
|
|
26
32
|
- bin/gdb.rb
|
27
33
|
- ext/Makefile
|
28
34
|
- ext/extconf.rb
|
29
|
-
- ext/src/gdb-7.
|
35
|
+
- ext/src/gdb-7.2.tar.bz2
|
30
36
|
- gdb.rb.gemspec
|
31
|
-
- patches/gdb-breakpoints.patch
|
32
|
-
- patches/gdb-eval.patch
|
33
37
|
- patches/gdb-leak.patch
|
34
38
|
- patches/gdb-strings.patch
|
35
39
|
- scripts/ruby-gdb.py
|
@@ -43,23 +47,29 @@ rdoc_options: []
|
|
43
47
|
require_paths:
|
44
48
|
- lib
|
45
49
|
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
46
51
|
requirements:
|
47
52
|
- - ">="
|
48
53
|
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
|
+
segments:
|
56
|
+
- 0
|
49
57
|
version: "0"
|
50
|
-
version:
|
51
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
52
60
|
requirements:
|
53
61
|
- - ">="
|
54
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
55
66
|
version: "0"
|
56
|
-
version:
|
57
67
|
requirements: []
|
58
68
|
|
59
69
|
rubyforge_project: gdb-rb
|
60
|
-
rubygems_version: 1.3.
|
70
|
+
rubygems_version: 1.3.7
|
61
71
|
signing_key:
|
62
72
|
specification_version: 3
|
63
|
-
summary: gdb hooks for MRI
|
73
|
+
summary: gdb hooks for MRI and REE
|
64
74
|
test_files: []
|
65
75
|
|
@@ -1,744 +0,0 @@
|
|
1
|
-
diff --git a/Makefile.in b/Makefile.in
|
2
|
-
index 7d53205..ed6729e 100644
|
3
|
-
--- a/Makefile.in
|
4
|
-
+++ b/Makefile.in
|
5
|
-
@@ -267,6 +267,7 @@ SUBDIR_TUI_CFLAGS= \
|
6
|
-
#
|
7
|
-
SUBDIR_PYTHON_OBS = \
|
8
|
-
python.o \
|
9
|
-
+ py-breakpoint.o \
|
10
|
-
py-cmd.o \
|
11
|
-
py-frame.o \
|
12
|
-
py-function.o \
|
13
|
-
@@ -277,6 +278,7 @@ SUBDIR_PYTHON_OBS = \
|
14
|
-
py-value.o
|
15
|
-
SUBDIR_PYTHON_SRCS = \
|
16
|
-
python/python.c \
|
17
|
-
+ python/py-breakpoint.c \
|
18
|
-
python/py-cmd.c \
|
19
|
-
python/py-frame.c \
|
20
|
-
python/py-function.c \
|
21
|
-
@@ -1963,6 +1965,10 @@ python.o: $(srcdir)/python/python.c
|
22
|
-
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
|
23
|
-
$(POSTCOMPILE)
|
24
|
-
|
25
|
-
+py-breakpoint.o: $(srcdir)/python/py-breakpoint.c
|
26
|
-
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-breakpoint.c
|
27
|
-
+ $(POSTCOMPILE)
|
28
|
-
+
|
29
|
-
py-cmd.o: $(srcdir)/python/py-cmd.c
|
30
|
-
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-cmd.c
|
31
|
-
$(POSTCOMPILE)
|
32
|
-
diff --git a/python/py-breakpoint.c b/python/py-breakpoint.c
|
33
|
-
new file mode 100644
|
34
|
-
index 0000000..913deec
|
35
|
-
--- /dev/null
|
36
|
-
+++ b/python/py-breakpoint.c
|
37
|
-
@@ -0,0 +1,665 @@
|
38
|
-
+/* Python interface to breakpoints
|
39
|
-
+
|
40
|
-
+ Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
41
|
-
+
|
42
|
-
+ This file is part of GDB.
|
43
|
-
+
|
44
|
-
+ This program is free software; you can redistribute it and/or modify
|
45
|
-
+ it under the terms of the GNU General Public License as published by
|
46
|
-
+ the Free Software Foundation; either version 3 of the License, or
|
47
|
-
+ (at your option) any later version.
|
48
|
-
+
|
49
|
-
+ This program is distributed in the hope that it will be useful,
|
50
|
-
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
51
|
-
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
52
|
-
+ GNU General Public License for more details.
|
53
|
-
+
|
54
|
-
+ You should have received a copy of the GNU General Public License
|
55
|
-
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
56
|
-
+
|
57
|
-
+#include "defs.h"
|
58
|
-
+#include "value.h"
|
59
|
-
+#include "exceptions.h"
|
60
|
-
+#include "python-internal.h"
|
61
|
-
+#include "charset.h"
|
62
|
-
+#include "breakpoint.h"
|
63
|
-
+#include "gdbcmd.h"
|
64
|
-
+#include "gdbthread.h"
|
65
|
-
+#include "observer.h"
|
66
|
-
+#include "arch-utils.h"
|
67
|
-
+#include "language.h"
|
68
|
-
+
|
69
|
-
+/* From breakpoint.c. */
|
70
|
-
+extern struct breakpoint *breakpoint_chain;
|
71
|
-
+
|
72
|
-
+
|
73
|
-
+typedef struct breakpoint_object breakpoint_object;
|
74
|
-
+
|
75
|
-
+static PyTypeObject breakpoint_object_type;
|
76
|
-
+
|
77
|
-
+/* A dynamically allocated vector of breakpoint objects. Each
|
78
|
-
+ breakpoint has a number. A breakpoint is valid if its slot in this
|
79
|
-
+ vector is non-null. When a breakpoint is deleted, we drop our
|
80
|
-
+ reference to it and zero its slot; this is how we let the Python
|
81
|
-
+ object have a lifetime which is independent from that of the gdb
|
82
|
-
+ breakpoint. */
|
83
|
-
+static breakpoint_object **bppy_breakpoints;
|
84
|
-
+
|
85
|
-
+/* Number of slots in bppy_breakpoints. */
|
86
|
-
+static int bppy_slots;
|
87
|
-
+
|
88
|
-
+/* Number of live breakpoints. */
|
89
|
-
+static int bppy_live;
|
90
|
-
+
|
91
|
-
+/* Variables used to pass information between the Breakpoint
|
92
|
-
+ constructor and the breakpoint-created hook function. */
|
93
|
-
+static breakpoint_object *bppy_pending_object;
|
94
|
-
+
|
95
|
-
+struct breakpoint_object
|
96
|
-
+{
|
97
|
-
+ PyObject_HEAD
|
98
|
-
+
|
99
|
-
+ /* The breakpoint number according to gdb. */
|
100
|
-
+ int number;
|
101
|
-
+
|
102
|
-
+ /* The gdb breakpoint object, or NULL if the breakpoint has been
|
103
|
-
+ deleted. */
|
104
|
-
+ struct breakpoint *bp;
|
105
|
-
+};
|
106
|
-
+
|
107
|
-
+/* Evaluate to true if the breakpoint NUM is valid, false otherwise. */
|
108
|
-
+#define BPPY_VALID_P(Num) \
|
109
|
-
+ ((Num) >= 0 \
|
110
|
-
+ && (Num) < bppy_slots \
|
111
|
-
+ && bppy_breakpoints[Num] != NULL)
|
112
|
-
+
|
113
|
-
+/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
|
114
|
-
+ exception if it is invalid. */
|
115
|
-
+#define BPPY_REQUIRE_VALID(Breakpoint) \
|
116
|
-
+ do { \
|
117
|
-
+ if (! BPPY_VALID_P ((Breakpoint)->number)) \
|
118
|
-
+ return PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \
|
119
|
-
+ (Breakpoint)->number); \
|
120
|
-
+ } while (0)
|
121
|
-
+
|
122
|
-
+/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
|
123
|
-
+ exception if it is invalid. This macro is for use in setter functions. */
|
124
|
-
+#define BPPY_SET_REQUIRE_VALID(Breakpoint) \
|
125
|
-
+ do { \
|
126
|
-
+ if (! BPPY_VALID_P ((Breakpoint)->number)) \
|
127
|
-
+ { \
|
128
|
-
+ PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \
|
129
|
-
+ (Breakpoint)->number); \
|
130
|
-
+ return -1; \
|
131
|
-
+ } \
|
132
|
-
+ } while (0)
|
133
|
-
+
|
134
|
-
+/* Python function which checks the validity of a breakpoint object. */
|
135
|
-
+static PyObject *
|
136
|
-
+bppy_is_valid (PyObject *self, PyObject *args)
|
137
|
-
+{
|
138
|
-
+ if (((breakpoint_object *) self)->bp)
|
139
|
-
+ Py_RETURN_TRUE;
|
140
|
-
+ Py_RETURN_FALSE;
|
141
|
-
+}
|
142
|
-
+
|
143
|
-
+/* Python function to test whether or not the breakpoint is enabled. */
|
144
|
-
+static PyObject *
|
145
|
-
+bppy_get_enabled (PyObject *self, void *closure)
|
146
|
-
+{
|
147
|
-
+ if (! ((breakpoint_object *) self)->bp)
|
148
|
-
+ Py_RETURN_FALSE;
|
149
|
-
+ /* Not clear what we really want here. */
|
150
|
-
+ if (((breakpoint_object *) self)->bp->enable_state == bp_enabled)
|
151
|
-
+ Py_RETURN_TRUE;
|
152
|
-
+ Py_RETURN_FALSE;
|
153
|
-
+}
|
154
|
-
+
|
155
|
-
+/* Python function to test whether or not the breakpoint is silent. */
|
156
|
-
+static PyObject *
|
157
|
-
+bppy_get_silent (PyObject *self, void *closure)
|
158
|
-
+{
|
159
|
-
+ BPPY_REQUIRE_VALID ((breakpoint_object *) self);
|
160
|
-
+ if (((breakpoint_object *) self)->bp->silent)
|
161
|
-
+ Py_RETURN_TRUE;
|
162
|
-
+ Py_RETURN_FALSE;
|
163
|
-
+}
|
164
|
-
+
|
165
|
-
+/* Python function to set the enabled state of a breakpoint. */
|
166
|
-
+static int
|
167
|
-
+bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure)
|
168
|
-
+{
|
169
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
170
|
-
+ int cmp;
|
171
|
-
+
|
172
|
-
+ BPPY_SET_REQUIRE_VALID (self_bp);
|
173
|
-
+
|
174
|
-
+ if (newvalue == NULL)
|
175
|
-
+ {
|
176
|
-
+ PyErr_SetString (PyExc_TypeError, "cannot delete `enabled' attribute");
|
177
|
-
+ return -1;
|
178
|
-
+ }
|
179
|
-
+ else if (! PyBool_Check (newvalue))
|
180
|
-
+ {
|
181
|
-
+ PyErr_SetString (PyExc_TypeError,
|
182
|
-
+ "the value of `enabled' must be a boolean");
|
183
|
-
+ return -1;
|
184
|
-
+ }
|
185
|
-
+
|
186
|
-
+ cmp = PyObject_IsTrue (newvalue);
|
187
|
-
+ if (cmp < 0)
|
188
|
-
+ return -1;
|
189
|
-
+ else if (cmp == 1)
|
190
|
-
+ enable_breakpoint (self_bp->bp);
|
191
|
-
+ else
|
192
|
-
+ disable_breakpoint (self_bp->bp);
|
193
|
-
+ return 0;
|
194
|
-
+}
|
195
|
-
+
|
196
|
-
+/* Python function to set the 'silent' state of a breakpoint. */
|
197
|
-
+static int
|
198
|
-
+bppy_set_silent (PyObject *self, PyObject *newvalue, void *closure)
|
199
|
-
+{
|
200
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
201
|
-
+ int cmp;
|
202
|
-
+
|
203
|
-
+ BPPY_SET_REQUIRE_VALID (self_bp);
|
204
|
-
+
|
205
|
-
+ if (newvalue == NULL)
|
206
|
-
+ {
|
207
|
-
+ PyErr_SetString (PyExc_TypeError, "cannot delete `silent' attribute");
|
208
|
-
+ return -1;
|
209
|
-
+ }
|
210
|
-
+ else if (! PyBool_Check (newvalue))
|
211
|
-
+ {
|
212
|
-
+ PyErr_SetString (PyExc_TypeError,
|
213
|
-
+ "the value of `silent' must be a boolean");
|
214
|
-
+ return -1;
|
215
|
-
+ }
|
216
|
-
+
|
217
|
-
+ cmp = PyObject_IsTrue (newvalue);
|
218
|
-
+ if (cmp < 0)
|
219
|
-
+ return -1;
|
220
|
-
+ else
|
221
|
-
+ self_bp->bp->silent = cmp;
|
222
|
-
+
|
223
|
-
+ return 0;
|
224
|
-
+}
|
225
|
-
+
|
226
|
-
+/* Python function to set the thread of a breakpoint. */
|
227
|
-
+static int
|
228
|
-
+bppy_set_thread (PyObject *self, PyObject *newvalue, void *closure)
|
229
|
-
+{
|
230
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
231
|
-
+ int id;
|
232
|
-
+
|
233
|
-
+ BPPY_SET_REQUIRE_VALID (self_bp);
|
234
|
-
+
|
235
|
-
+ if (newvalue == NULL)
|
236
|
-
+ {
|
237
|
-
+ PyErr_SetString (PyExc_TypeError, "cannot delete `thread' attribute");
|
238
|
-
+ return -1;
|
239
|
-
+ }
|
240
|
-
+ else if (PyInt_Check (newvalue))
|
241
|
-
+ {
|
242
|
-
+ id = (int) PyInt_AsLong (newvalue);
|
243
|
-
+ if (! valid_thread_id (id))
|
244
|
-
+ {
|
245
|
-
+ PyErr_SetString (PyExc_RuntimeError, "invalid thread id");
|
246
|
-
+ return -1;
|
247
|
-
+ }
|
248
|
-
+ }
|
249
|
-
+ else if (newvalue == Py_None)
|
250
|
-
+ id = -1;
|
251
|
-
+ else
|
252
|
-
+ {
|
253
|
-
+ PyErr_SetString (PyExc_TypeError,
|
254
|
-
+ "the value of `thread' must be an integer or None");
|
255
|
-
+ return -1;
|
256
|
-
+ }
|
257
|
-
+
|
258
|
-
+ self_bp->bp->thread = id;
|
259
|
-
+
|
260
|
-
+ return 0;
|
261
|
-
+}
|
262
|
-
+
|
263
|
-
+/* Python function to set the ignore count of a breakpoint. */
|
264
|
-
+static int
|
265
|
-
+bppy_set_ignore_count (PyObject *self, PyObject *newvalue, void *closure)
|
266
|
-
+{
|
267
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
268
|
-
+ long value;
|
269
|
-
+
|
270
|
-
+ BPPY_SET_REQUIRE_VALID (self_bp);
|
271
|
-
+
|
272
|
-
+ if (newvalue == NULL)
|
273
|
-
+ {
|
274
|
-
+ PyErr_SetString (PyExc_TypeError,
|
275
|
-
+ "cannot delete `ignore_count' attribute");
|
276
|
-
+ return -1;
|
277
|
-
+ }
|
278
|
-
+ else if (! PyInt_Check (newvalue))
|
279
|
-
+ {
|
280
|
-
+ PyErr_SetString (PyExc_TypeError,
|
281
|
-
+ "the value of `ignore_count' must be an integer");
|
282
|
-
+ return -1;
|
283
|
-
+ }
|
284
|
-
+
|
285
|
-
+ value = PyInt_AsLong (newvalue);
|
286
|
-
+ if (value < 0)
|
287
|
-
+ value = 0;
|
288
|
-
+ set_ignore_count (self_bp->number, (int) value, 0);
|
289
|
-
+
|
290
|
-
+ return 0;
|
291
|
-
+}
|
292
|
-
+
|
293
|
-
+/* Python function to set the hit count of a breakpoint. */
|
294
|
-
+static int
|
295
|
-
+bppy_set_hit_count (PyObject *self, PyObject *newvalue, void *closure)
|
296
|
-
+{
|
297
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
298
|
-
+
|
299
|
-
+ BPPY_SET_REQUIRE_VALID (self_bp);
|
300
|
-
+
|
301
|
-
+ if (newvalue == NULL)
|
302
|
-
+ {
|
303
|
-
+ PyErr_SetString (PyExc_TypeError, "cannot delete `hit_count' attribute");
|
304
|
-
+ return -1;
|
305
|
-
+ }
|
306
|
-
+ else if (! PyInt_Check (newvalue) || PyInt_AsLong (newvalue) != 0)
|
307
|
-
+ {
|
308
|
-
+ PyErr_SetString (PyExc_AttributeError,
|
309
|
-
+ "the value of `hit_count' must be zero");
|
310
|
-
+ return -1;
|
311
|
-
+ }
|
312
|
-
+
|
313
|
-
+ self_bp->bp->hit_count = 0;
|
314
|
-
+
|
315
|
-
+ return 0;
|
316
|
-
+}
|
317
|
-
+
|
318
|
-
+/* Python function to get the location of a breakpoint. */
|
319
|
-
+static PyObject *
|
320
|
-
+bppy_get_location (PyObject *self, void *closure)
|
321
|
-
+{
|
322
|
-
+ char *str;
|
323
|
-
+
|
324
|
-
+ BPPY_REQUIRE_VALID ((breakpoint_object *) self);
|
325
|
-
+ str = ((breakpoint_object *) self)->bp->addr_string;
|
326
|
-
+ /* FIXME: watchpoints? tracepoints? */
|
327
|
-
+ if (! str)
|
328
|
-
+ str = "";
|
329
|
-
+ return PyString_Decode (str, strlen (str), host_charset (), NULL);
|
330
|
-
+}
|
331
|
-
+
|
332
|
-
+// /* Python function to get the condition expression of a breakpoint. */
|
333
|
-
+// static PyObject *
|
334
|
-
+// bppy_get_condition (PyObject *self, void *closure)
|
335
|
-
+// {
|
336
|
-
+// char *str;
|
337
|
-
+// BPPY_REQUIRE_VALID ((breakpoint_object *) self);
|
338
|
-
+//
|
339
|
-
+// str = ((breakpoint_object *) self)->bp->cond_string;
|
340
|
-
+// if (! str)
|
341
|
-
+// Py_RETURN_NONE;
|
342
|
-
+// return PyString_Decode (str, strlen (str), host_charset (), NULL);
|
343
|
-
+// }
|
344
|
-
+
|
345
|
-
+// static int
|
346
|
-
+// bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
|
347
|
-
+// {
|
348
|
-
+// char *exp;
|
349
|
-
+// breakpoint_object *self_bp = (breakpoint_object *) self;
|
350
|
-
+// volatile struct gdb_exception except;
|
351
|
-
+//
|
352
|
-
+// BPPY_SET_REQUIRE_VALID (self_bp);
|
353
|
-
+//
|
354
|
-
+// if (newvalue == NULL)
|
355
|
-
+// {
|
356
|
-
+// PyErr_SetString (PyExc_TypeError, "cannot delete `condition' attribute");
|
357
|
-
+// return -1;
|
358
|
-
+// }
|
359
|
-
+// else if (newvalue == Py_None)
|
360
|
-
+// exp = "";
|
361
|
-
+// else
|
362
|
-
+// {
|
363
|
-
+// exp = python_string_to_host_string (newvalue);
|
364
|
-
+// if (exp == NULL)
|
365
|
-
+// return -1;
|
366
|
-
+// }
|
367
|
-
+//
|
368
|
-
+// TRY_CATCH (except, RETURN_MASK_ALL)
|
369
|
-
+// {
|
370
|
-
+// set_breakpoint_condition (self_bp->bp, exp, 0);
|
371
|
-
+// }
|
372
|
-
+// GDB_PY_HANDLE_EXCEPTION (except);
|
373
|
-
+//
|
374
|
-
+// return 0;
|
375
|
-
+// }
|
376
|
-
+
|
377
|
-
+/* Python function to get the commands attached to a breakpoint. */
|
378
|
-
+static PyObject *
|
379
|
-
+bppy_get_commands (PyObject *self, void *closure)
|
380
|
-
+{
|
381
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
382
|
-
+ long length;
|
383
|
-
+ volatile struct gdb_exception except;
|
384
|
-
+ struct ui_file *string_file;
|
385
|
-
+ struct cleanup *chain;
|
386
|
-
+ PyObject *result;
|
387
|
-
+ char *cmdstr;
|
388
|
-
+
|
389
|
-
+ BPPY_REQUIRE_VALID (self_bp);
|
390
|
-
+
|
391
|
-
+ if (! self_bp->bp->commands)
|
392
|
-
+ Py_RETURN_NONE;
|
393
|
-
+
|
394
|
-
+ string_file = mem_fileopen ();
|
395
|
-
+ chain = make_cleanup_ui_file_delete (string_file);
|
396
|
-
+
|
397
|
-
+ TRY_CATCH (except, RETURN_MASK_ALL)
|
398
|
-
+ {
|
399
|
-
+ /* FIXME: this can fail. Maybe we need to be making a new
|
400
|
-
+ ui_out object here? */
|
401
|
-
+ ui_out_redirect (uiout, string_file);
|
402
|
-
+ print_command_lines (uiout, self_bp->bp->commands, 0);
|
403
|
-
+ ui_out_redirect (uiout, NULL);
|
404
|
-
+ }
|
405
|
-
+ cmdstr = ui_file_xstrdup (string_file, &length);
|
406
|
-
+ GDB_PY_HANDLE_EXCEPTION (except);
|
407
|
-
+
|
408
|
-
+ result = PyString_Decode (cmdstr, strlen (cmdstr), host_charset (), NULL);
|
409
|
-
+ do_cleanups (chain);
|
410
|
-
+ xfree (cmdstr);
|
411
|
-
+ return result;
|
412
|
-
+}
|
413
|
-
+
|
414
|
-
+/* Python function to get the breakpoint's number. */
|
415
|
-
+static PyObject *
|
416
|
-
+bppy_get_number (PyObject *self, void *closure)
|
417
|
-
+{
|
418
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
419
|
-
+
|
420
|
-
+ BPPY_REQUIRE_VALID (self_bp);
|
421
|
-
+
|
422
|
-
+ return PyInt_FromLong (self_bp->number);
|
423
|
-
+}
|
424
|
-
+
|
425
|
-
+/* Python function to get the breakpoint's thread ID. */
|
426
|
-
+static PyObject *
|
427
|
-
+bppy_get_thread (PyObject *self, void *closure)
|
428
|
-
+{
|
429
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
430
|
-
+
|
431
|
-
+ BPPY_REQUIRE_VALID (self_bp);
|
432
|
-
+
|
433
|
-
+ if (self_bp->bp->thread == -1)
|
434
|
-
+ Py_RETURN_NONE;
|
435
|
-
+
|
436
|
-
+ return PyInt_FromLong (self_bp->bp->thread);
|
437
|
-
+}
|
438
|
-
+
|
439
|
-
+/* Python function to get the breakpoint's hit count. */
|
440
|
-
+static PyObject *
|
441
|
-
+bppy_get_hit_count (PyObject *self, void *closure)
|
442
|
-
+{
|
443
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
444
|
-
+
|
445
|
-
+ BPPY_REQUIRE_VALID (self_bp);
|
446
|
-
+
|
447
|
-
+ return PyInt_FromLong (self_bp->bp->hit_count);
|
448
|
-
+}
|
449
|
-
+
|
450
|
-
+/* Python function to get the breakpoint's ignore count. */
|
451
|
-
+static PyObject *
|
452
|
-
+bppy_get_ignore_count (PyObject *self, void *closure)
|
453
|
-
+{
|
454
|
-
+ breakpoint_object *self_bp = (breakpoint_object *) self;
|
455
|
-
+
|
456
|
-
+ BPPY_REQUIRE_VALID (self_bp);
|
457
|
-
+
|
458
|
-
+ return PyInt_FromLong (self_bp->bp->ignore_count);
|
459
|
-
+}
|
460
|
-
+
|
461
|
-
+/* Python function to create a new breakpoint. */
|
462
|
-
+static PyObject *
|
463
|
-
+bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
|
464
|
-
+{
|
465
|
-
+ PyObject *result;
|
466
|
-
+ char *spec;
|
467
|
-
+ volatile struct gdb_exception except;
|
468
|
-
+
|
469
|
-
+ /* FIXME: allow condition, thread, temporary, ... ? */
|
470
|
-
+ if (! PyArg_ParseTuple (args, "s", &spec))
|
471
|
-
+ return NULL;
|
472
|
-
+ result = subtype->tp_alloc (subtype, 0);
|
473
|
-
+ if (! result)
|
474
|
-
+ return NULL;
|
475
|
-
+ bppy_pending_object = (breakpoint_object *) result;
|
476
|
-
+ bppy_pending_object->number = -1;
|
477
|
-
+ bppy_pending_object->bp = NULL;
|
478
|
-
+
|
479
|
-
+ TRY_CATCH (except, RETURN_MASK_ALL)
|
480
|
-
+ {
|
481
|
-
+ set_breakpoint (python_gdbarch, spec, NULL, 0, 0, -1, 0,
|
482
|
-
+ AUTO_BOOLEAN_TRUE, 1);
|
483
|
-
+ }
|
484
|
-
+ if (except.reason < 0)
|
485
|
-
+ {
|
486
|
-
+ subtype->tp_free (result);
|
487
|
-
+ return PyErr_Format (except.reason == RETURN_QUIT
|
488
|
-
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
|
489
|
-
+ "%s", except.message);
|
490
|
-
+ }
|
491
|
-
+
|
492
|
-
+ BPPY_REQUIRE_VALID ((breakpoint_object *) result);
|
493
|
-
+ return result;
|
494
|
-
+}
|
495
|
-
+
|
496
|
-
+
|
497
|
-
+
|
498
|
-
+/* Static function to return a tuple holding all breakpoints. */
|
499
|
-
+
|
500
|
-
+PyObject *
|
501
|
-
+gdbpy_breakpoints (PyObject *self, PyObject *args)
|
502
|
-
+{
|
503
|
-
+ PyObject *result;
|
504
|
-
+
|
505
|
-
+ if (bppy_live == 0)
|
506
|
-
+ Py_RETURN_NONE;
|
507
|
-
+
|
508
|
-
+ result = PyTuple_New (bppy_live);
|
509
|
-
+ if (result)
|
510
|
-
+ {
|
511
|
-
+ int i, out = 0;
|
512
|
-
+ for (i = 0; out < bppy_live; ++i)
|
513
|
-
+ {
|
514
|
-
+ if (! bppy_breakpoints[i])
|
515
|
-
+ continue;
|
516
|
-
+ Py_INCREF (bppy_breakpoints[i]);
|
517
|
-
+ PyTuple_SetItem (result, out, (PyObject *) bppy_breakpoints[i]);
|
518
|
-
+ ++out;
|
519
|
-
+ }
|
520
|
-
+ }
|
521
|
-
+ return result;
|
522
|
-
+}
|
523
|
-
+
|
524
|
-
+
|
525
|
-
+
|
526
|
-
+/* Event callback functions. */
|
527
|
-
+
|
528
|
-
+/* Callback that is used when a breakpoint is created. This function
|
529
|
-
+ will create a new Python breakpoint object. */
|
530
|
-
+static void
|
531
|
-
+gdbpy_breakpoint_created (int num)
|
532
|
-
+{
|
533
|
-
+ breakpoint_object *newbp;
|
534
|
-
+ struct breakpoint *bp;
|
535
|
-
+ struct cleanup *cleanup;
|
536
|
-
+
|
537
|
-
+ if (num < 0)
|
538
|
-
+ return;
|
539
|
-
+
|
540
|
-
+ for (bp = breakpoint_chain; bp; bp = bp->next)
|
541
|
-
+ if (bp->number == num)
|
542
|
-
+ break;
|
543
|
-
+ if (! bp)
|
544
|
-
+ return;
|
545
|
-
+
|
546
|
-
+ if (num >= bppy_slots)
|
547
|
-
+ {
|
548
|
-
+ int old = bppy_slots;
|
549
|
-
+ bppy_slots = bppy_slots * 2 + 10;
|
550
|
-
+ bppy_breakpoints
|
551
|
-
+ = (breakpoint_object **) xrealloc (bppy_breakpoints,
|
552
|
-
+ (bppy_slots
|
553
|
-
+ * sizeof (breakpoint_object *)));
|
554
|
-
+ memset (&bppy_breakpoints[old], 0,
|
555
|
-
+ (bppy_slots - old) * sizeof (PyObject *));
|
556
|
-
+ }
|
557
|
-
+
|
558
|
-
+ ++bppy_live;
|
559
|
-
+
|
560
|
-
+ cleanup = ensure_python_env (get_current_arch (), current_language);
|
561
|
-
+
|
562
|
-
+ if (bppy_pending_object)
|
563
|
-
+ {
|
564
|
-
+ newbp = bppy_pending_object;
|
565
|
-
+ bppy_pending_object = NULL;
|
566
|
-
+ }
|
567
|
-
+ else
|
568
|
-
+ newbp = PyObject_New (breakpoint_object, &breakpoint_object_type);
|
569
|
-
+ if (newbp)
|
570
|
-
+ {
|
571
|
-
+ // PyObject *hookfn;
|
572
|
-
+
|
573
|
-
+ newbp->number = num;
|
574
|
-
+ newbp->bp = bp;
|
575
|
-
+ bppy_breakpoints[num] = newbp;
|
576
|
-
+
|
577
|
-
+ // hookfn = gdbpy_get_hook_function ("new_breakpoint");
|
578
|
-
+ // if (hookfn)
|
579
|
-
+ // {
|
580
|
-
+ // PyObject *result;
|
581
|
-
+ // result = PyObject_CallFunctionObjArgs (hookfn, newbp, NULL);
|
582
|
-
+ // if (result)
|
583
|
-
+ // {
|
584
|
-
+ // Py_DECREF (result);
|
585
|
-
+ // }
|
586
|
-
+ // Py_DECREF (hookfn);
|
587
|
-
+ // }
|
588
|
-
+ }
|
589
|
-
+
|
590
|
-
+ /* Just ignore errors here. */
|
591
|
-
+ PyErr_Clear ();
|
592
|
-
+
|
593
|
-
+ do_cleanups (cleanup);
|
594
|
-
+}
|
595
|
-
+
|
596
|
-
+/* Callback that is used when a breakpoint is deleted. This will
|
597
|
-
+ invalidate the corresponding Python object. */
|
598
|
-
+static void
|
599
|
-
+gdbpy_breakpoint_deleted (int num)
|
600
|
-
+{
|
601
|
-
+ struct cleanup *cleanup;
|
602
|
-
+
|
603
|
-
+ cleanup = ensure_python_env (get_current_arch (), current_language);
|
604
|
-
+ if (BPPY_VALID_P (num))
|
605
|
-
+ {
|
606
|
-
+ bppy_breakpoints[num]->bp = NULL;
|
607
|
-
+ Py_DECREF (bppy_breakpoints[num]);
|
608
|
-
+ bppy_breakpoints[num] = NULL;
|
609
|
-
+ --bppy_live;
|
610
|
-
+ }
|
611
|
-
+ do_cleanups (cleanup);
|
612
|
-
+}
|
613
|
-
+
|
614
|
-
+
|
615
|
-
+
|
616
|
-
+/* Initialize the Python breakpoint code. */
|
617
|
-
+void
|
618
|
-
+gdbpy_initialize_breakpoints (void)
|
619
|
-
+{
|
620
|
-
+ breakpoint_object_type.tp_new = bppy_new;
|
621
|
-
+ if (PyType_Ready (&breakpoint_object_type) < 0)
|
622
|
-
+ return;
|
623
|
-
+
|
624
|
-
+ Py_INCREF (&breakpoint_object_type);
|
625
|
-
+ PyModule_AddObject (gdb_module, "Breakpoint",
|
626
|
-
+ (PyObject *) &breakpoint_object_type);
|
627
|
-
+
|
628
|
-
+ observer_attach_breakpoint_created (gdbpy_breakpoint_created);
|
629
|
-
+ observer_attach_breakpoint_deleted (gdbpy_breakpoint_deleted);
|
630
|
-
+}
|
631
|
-
+
|
632
|
-
+
|
633
|
-
+
|
634
|
-
+static PyGetSetDef breakpoint_object_getset[] = {
|
635
|
-
+ { "enabled", bppy_get_enabled, bppy_set_enabled,
|
636
|
-
+ "Boolean telling whether the breakpoint is enabled.", NULL },
|
637
|
-
+ { "silent", bppy_get_silent, bppy_set_silent,
|
638
|
-
+ "Boolean telling whether the breakpoint is silent.", NULL },
|
639
|
-
+ { "thread", bppy_get_thread, bppy_set_thread,
|
640
|
-
+ "Thread ID for the breakpoint.\n\
|
641
|
-
+If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\
|
642
|
-
+If the value is None, then this breakpoint not thread-specific.\n\
|
643
|
-
+No other type of value can be used.", NULL },
|
644
|
-
+ { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count,
|
645
|
-
+ "Number of times this breakpoint should be automatically continued.",
|
646
|
-
+ NULL },
|
647
|
-
+ { "number", bppy_get_number, NULL,
|
648
|
-
+ "Breakpoint's number assigned by GDB.", NULL },
|
649
|
-
+ { "hit_count", bppy_get_hit_count, bppy_set_hit_count,
|
650
|
-
+ "Number of times the breakpoint has been hit.\n\
|
651
|
-
+Can be set to zero to clear the count. No other value is valid\n\
|
652
|
-
+when setting this property.", NULL },
|
653
|
-
+ { "location", bppy_get_location, NULL,
|
654
|
-
+ "Location of the breakpoint, as specified by the user.", NULL},
|
655
|
-
+// { "condition", bppy_get_condition, bppy_set_condition,
|
656
|
-
+// "Condition of the breakpoint, as specified by the user, or None if no condition set."},
|
657
|
-
+ { "commands", bppy_get_commands, NULL,
|
658
|
-
+ "Commands of the breakpoint, as specified by the user."},
|
659
|
-
+ { NULL } /* Sentinel. */
|
660
|
-
+};
|
661
|
-
+
|
662
|
-
+static PyMethodDef breakpoint_object_methods[] =
|
663
|
-
+{
|
664
|
-
+ { "is_valid", bppy_is_valid, METH_NOARGS,
|
665
|
-
+ "Return true if this breakpoint is valid, false if not." },
|
666
|
-
+ { NULL } /* Sentinel. */
|
667
|
-
+};
|
668
|
-
+
|
669
|
-
+static PyTypeObject breakpoint_object_type =
|
670
|
-
+{
|
671
|
-
+ PyObject_HEAD_INIT (NULL)
|
672
|
-
+ 0, /*ob_size*/
|
673
|
-
+ "gdb.Breakpoint", /*tp_name*/
|
674
|
-
+ sizeof (breakpoint_object), /*tp_basicsize*/
|
675
|
-
+ 0, /*tp_itemsize*/
|
676
|
-
+ 0, /*tp_dealloc*/
|
677
|
-
+ 0, /*tp_print*/
|
678
|
-
+ 0, /*tp_getattr*/
|
679
|
-
+ 0, /*tp_setattr*/
|
680
|
-
+ 0, /*tp_compare*/
|
681
|
-
+ 0, /*tp_repr*/
|
682
|
-
+ 0, /*tp_as_number*/
|
683
|
-
+ 0, /*tp_as_sequence*/
|
684
|
-
+ 0, /*tp_as_mapping*/
|
685
|
-
+ 0, /*tp_hash */
|
686
|
-
+ 0, /*tp_call*/
|
687
|
-
+ 0, /*tp_str*/
|
688
|
-
+ 0, /*tp_getattro*/
|
689
|
-
+ 0, /*tp_setattro*/
|
690
|
-
+ 0, /*tp_as_buffer*/
|
691
|
-
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
692
|
-
+ "GDB breakpoint object", /* tp_doc */
|
693
|
-
+ 0, /* tp_traverse */
|
694
|
-
+ 0, /* tp_clear */
|
695
|
-
+ 0, /* tp_richcompare */
|
696
|
-
+ 0, /* tp_weaklistoffset */
|
697
|
-
+ 0, /* tp_iter */
|
698
|
-
+ 0, /* tp_iternext */
|
699
|
-
+ breakpoint_object_methods, /* tp_methods */
|
700
|
-
+ 0, /* tp_members */
|
701
|
-
+ breakpoint_object_getset /* tp_getset */
|
702
|
-
+};
|
703
|
-
diff --git a/python/python-internal.h b/python/python-internal.h
|
704
|
-
index fbf8247..fa4a62b 100644
|
705
|
-
--- a/python/python-internal.h
|
706
|
-
+++ b/python/python-internal.h
|
707
|
-
@@ -69,6 +69,7 @@ extern PyTypeObject value_object_type;
|
708
|
-
|
709
|
-
PyObject *gdbpy_history (PyObject *self, PyObject *args);
|
710
|
-
PyObject *gdbpy_eval (PyObject *self, PyObject *args);
|
711
|
-
+PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
|
712
|
-
PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
|
713
|
-
PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
|
714
|
-
PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
|
715
|
-
@@ -84,6 +85,7 @@ struct value *convert_value_from_python (PyObject *obj);
|
716
|
-
struct type *type_object_to_type (PyObject *obj);
|
717
|
-
|
718
|
-
void gdbpy_initialize_values (void);
|
719
|
-
+void gdbpy_initialize_breakpoints (void);
|
720
|
-
void gdbpy_initialize_frames (void);
|
721
|
-
void gdbpy_initialize_commands (void);
|
722
|
-
void gdbpy_initialize_types (void);
|
723
|
-
diff --git a/python/python.c b/python/python.c
|
724
|
-
index c96fa29..006ce29 100644
|
725
|
-
--- a/python/python.c
|
726
|
-
+++ b/python/python.c
|
727
|
-
@@ -594,6 +594,7 @@ Enables or disables auto-loading of Python code when an object is opened."),
|
728
|
-
PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
|
729
|
-
|
730
|
-
gdbpy_initialize_values ();
|
731
|
-
+ gdbpy_initialize_breakpoints ();
|
732
|
-
gdbpy_initialize_frames ();
|
733
|
-
gdbpy_initialize_commands ();
|
734
|
-
gdbpy_initialize_functions ();
|
735
|
-
@@ -658,6 +659,9 @@ static PyMethodDef GdbMethods[] =
|
736
|
-
{ "parameter", gdbpy_parameter, METH_VARARGS,
|
737
|
-
"Return a gdb parameter's value" },
|
738
|
-
|
739
|
-
+ { "breakpoints", gdbpy_breakpoints, METH_NOARGS,
|
740
|
-
+ "Return a tuple of all breakpoint objects" },
|
741
|
-
+
|
742
|
-
{ "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
|
743
|
-
"Find the default visualizer for a Value." },
|
744
|
-
|