OLD | NEW |
1 /* Python interface to finish breakpoints | 1 /* Python interface to finish breakpoints |
2 | 2 |
3 Copyright (C) 2011-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2011-2012 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GDB. | 5 This file is part of GDB. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 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 | 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 | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "defs.h" | 22 #include "defs.h" |
23 #include "exceptions.h" | 23 #include "exceptions.h" |
24 #include "python-internal.h" | 24 #include "python-internal.h" |
25 #include "breakpoint.h" | 25 #include "breakpoint.h" |
26 #include "frame.h" | 26 #include "frame.h" |
27 #include "gdbthread.h" | 27 #include "gdbthread.h" |
28 #include "arch-utils.h" | 28 #include "arch-utils.h" |
29 #include "language.h" | 29 #include "language.h" |
30 #include "observer.h" | 30 #include "observer.h" |
31 #include "inferior.h" | 31 #include "inferior.h" |
| 32 #include "block.h" |
32 | 33 |
33 static PyTypeObject finish_breakpoint_object_type; | 34 static PyTypeObject finish_breakpoint_object_type; |
34 | 35 |
35 /* Function that is called when a Python finish bp is found out of scope. */ | 36 /* Function that is called when a Python finish bp is found out of scope. */ |
36 static char * const outofscope_func = "out_of_scope"; | 37 static char * const outofscope_func = "out_of_scope"; |
37 | 38 |
38 /* struct implementing the gdb.FinishBreakpoint object by extending | 39 /* struct implementing the gdb.FinishBreakpoint object by extending |
39 the gdb.Breakpoint class. */ | 40 the gdb.Breakpoint class. */ |
40 struct finish_breakpoint_object | 41 struct finish_breakpoint_object |
41 { | 42 { |
42 /* gdb.Breakpoint base class. */ | 43 /* gdb.Breakpoint base class. */ |
43 breakpoint_object py_bp; | 44 breakpoint_object py_bp; |
44 /* gdb.Type object of the value return by the breakpointed function. | 45 /* gdb.Type object of the value return by the breakpointed function. |
45 May be NULL if no debug information was available or return type | 46 May be NULL if no debug information was available or return type |
46 was VOID. */ | 47 was VOID. */ |
47 PyObject *return_type; | 48 PyObject *return_type; |
48 /* gdb.Type object of the function finished by this breakpoint. Will be | 49 /* gdb.Value object of the function finished by this breakpoint. Will be |
49 NULL if return_type is NULL. */ | 50 NULL if return_type is NULL. */ |
50 PyObject *function_type; | 51 PyObject *function_value; |
51 /* When stopped at this FinishBreakpoint, gdb.Value object returned by | 52 /* When stopped at this FinishBreakpoint, gdb.Value object returned by |
52 the function; Py_None if the value is not computable; NULL if GDB is | 53 the function; Py_None if the value is not computable; NULL if GDB is |
53 not stopped at a FinishBreakpoint. */ | 54 not stopped at a FinishBreakpoint. */ |
54 PyObject *return_value; | 55 PyObject *return_value; |
55 }; | 56 }; |
56 | 57 |
57 /* Python function to get the 'return_value' attribute of | 58 /* Python function to get the 'return_value' attribute of |
58 FinishBreakpoint. */ | 59 FinishBreakpoint. */ |
59 | 60 |
60 static PyObject * | 61 static PyObject * |
(...skipping 10 matching lines...) Expand all Loading... |
71 } | 72 } |
72 | 73 |
73 /* Deallocate FinishBreakpoint object. */ | 74 /* Deallocate FinishBreakpoint object. */ |
74 | 75 |
75 static void | 76 static void |
76 bpfinishpy_dealloc (PyObject *self) | 77 bpfinishpy_dealloc (PyObject *self) |
77 { | 78 { |
78 struct finish_breakpoint_object *self_bpfinish = | 79 struct finish_breakpoint_object *self_bpfinish = |
79 (struct finish_breakpoint_object *) self; | 80 (struct finish_breakpoint_object *) self; |
80 | 81 |
81 Py_XDECREF (self_bpfinish->function_type); | 82 Py_XDECREF (self_bpfinish->function_value); |
82 Py_XDECREF (self_bpfinish->return_type); | 83 Py_XDECREF (self_bpfinish->return_type); |
83 Py_XDECREF (self_bpfinish->return_value); | 84 Py_XDECREF (self_bpfinish->return_value); |
84 } | 85 } |
85 | 86 |
86 /* Triggered when gdbpy_should_stop is about to execute the `stop' callback | 87 /* Triggered when gdbpy_should_stop is about to execute the `stop' callback |
87 of the gdb.FinishBreakpoint object BP_OBJ. Will compute and cache the | 88 of the gdb.FinishBreakpoint object BP_OBJ. Will compute and cache the |
88 `return_value', if possible. */ | 89 `return_value', if possible. */ |
89 | 90 |
90 void | 91 void |
91 bpfinishpy_pre_stop_hook (struct breakpoint_object *bp_obj) | 92 bpfinishpy_pre_stop_hook (struct breakpoint_object *bp_obj) |
92 { | 93 { |
93 struct finish_breakpoint_object *self_finishbp = | 94 struct finish_breakpoint_object *self_finishbp = |
94 (struct finish_breakpoint_object *) bp_obj; | 95 (struct finish_breakpoint_object *) bp_obj; |
95 volatile struct gdb_exception except; | 96 volatile struct gdb_exception except; |
96 | 97 |
97 /* Can compute return_value only once. */ | 98 /* Can compute return_value only once. */ |
98 gdb_assert (!self_finishbp->return_value); | 99 gdb_assert (!self_finishbp->return_value); |
99 | 100 |
100 if (!self_finishbp->return_type) | 101 if (!self_finishbp->return_type) |
101 return; | 102 return; |
102 | 103 |
103 TRY_CATCH (except, RETURN_MASK_ALL) | 104 TRY_CATCH (except, RETURN_MASK_ALL) |
104 { | 105 { |
105 struct value *ret = | 106 struct value *function = |
106 get_return_value (type_object_to_type (self_finishbp->function_type), | 107 value_object_to_value (self_finishbp->function_value); |
107 type_object_to_type (self_finishbp->return_type)); | 108 struct type *value_type = |
| 109 type_object_to_type (self_finishbp->return_type); |
| 110 struct value *ret = get_return_value (function, value_type); |
108 | 111 |
109 if (ret) | 112 if (ret) |
110 { | 113 { |
111 self_finishbp->return_value = value_to_value_object (ret); | 114 self_finishbp->return_value = value_to_value_object (ret); |
112 if (!self_finishbp->return_value) | 115 if (!self_finishbp->return_value) |
113 gdbpy_print_stack (); | 116 gdbpy_print_stack (); |
114 } | 117 } |
115 else | 118 else |
116 { | 119 { |
117 Py_INCREF (Py_None); | 120 Py_INCREF (Py_None); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 if (internal_bp == -1) | 229 if (internal_bp == -1) |
227 { | 230 { |
228 PyErr_SetString (PyExc_ValueError, | 231 PyErr_SetString (PyExc_ValueError, |
229 _("The value of `internal' must be a boolean.")); | 232 _("The value of `internal' must be a boolean.")); |
230 return -1; | 233 return -1; |
231 } | 234 } |
232 } | 235 } |
233 | 236 |
234 /* Find the function we will return from. */ | 237 /* Find the function we will return from. */ |
235 self_bpfinish->return_type = NULL; | 238 self_bpfinish->return_type = NULL; |
236 self_bpfinish->function_type = NULL; | 239 self_bpfinish->function_value = NULL; |
237 | 240 |
238 TRY_CATCH (except, RETURN_MASK_ALL) | 241 TRY_CATCH (except, RETURN_MASK_ALL) |
239 { | 242 { |
240 if (get_frame_pc_if_available (frame, &pc)) | 243 if (get_frame_pc_if_available (frame, &pc)) |
241 { | 244 { |
242 function = find_pc_function (pc); | 245 function = find_pc_function (pc); |
243 if (function != NULL) | 246 if (function != NULL) |
244 { | 247 { |
245 struct type *ret_type = | 248 struct type *ret_type = |
246 TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); | 249 TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); |
247 | 250 |
248 /* Remember only non-void return types. */ | 251 /* Remember only non-void return types. */ |
249 if (TYPE_CODE (ret_type) != TYPE_CODE_VOID) | 252 if (TYPE_CODE (ret_type) != TYPE_CODE_VOID) |
250 { | 253 { |
| 254 struct value *func_value; |
| 255 |
251 /* Ignore Python errors at this stage. */ | 256 /* Ignore Python errors at this stage. */ |
252 self_bpfinish->return_type = type_to_type_object (ret_type); | 257 self_bpfinish->return_type = type_to_type_object (ret_type); |
253 PyErr_Clear (); | 258 PyErr_Clear (); |
254 self_bpfinish->function_type = | 259 func_value = read_var_value (function, frame); |
255 type_to_type_object (SYMBOL_TYPE (function)); | 260 self_bpfinish->function_value = |
| 261 value_to_value_object (func_value); |
256 PyErr_Clear (); | 262 PyErr_Clear (); |
257 } | 263 } |
258 } | 264 } |
259 } | 265 } |
260 } | 266 } |
261 if (except.reason < 0 | 267 if (except.reason < 0 |
262 || !self_bpfinish->return_type || !self_bpfinish->function_type) | 268 || !self_bpfinish->return_type || !self_bpfinish->function_value) |
263 { | 269 { |
264 /* Won't be able to compute return value. */ | 270 /* Won't be able to compute return value. */ |
265 Py_XDECREF (self_bpfinish->return_type); | 271 Py_XDECREF (self_bpfinish->return_type); |
266 Py_XDECREF (self_bpfinish->function_type); | 272 Py_XDECREF (self_bpfinish->function_value); |
267 | 273 |
268 self_bpfinish->return_type = NULL; | 274 self_bpfinish->return_type = NULL; |
269 self_bpfinish->function_type = NULL; | 275 self_bpfinish->function_value = NULL; |
270 } | 276 } |
271 | 277 |
272 bppy_pending_object = &self_bpfinish->py_bp; | 278 bppy_pending_object = &self_bpfinish->py_bp; |
273 bppy_pending_object->number = -1; | 279 bppy_pending_object->number = -1; |
274 bppy_pending_object->bp = NULL; | 280 bppy_pending_object->bp = NULL; |
275 | 281 |
276 TRY_CATCH (except, RETURN_MASK_ALL) | 282 TRY_CATCH (except, RETURN_MASK_ALL) |
277 { | 283 { |
278 /* Set a breakpoint on the return address. */ | 284 /* Set a breakpoint on the return address. */ |
279 finish_pc = get_frame_pc (prev_frame); | 285 finish_pc = get_frame_pc (prev_frame); |
280 sprintf (small_buf, "*%s", hex_string (finish_pc)); | 286 xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (finish_pc)); |
281 addr_str = small_buf; | 287 addr_str = small_buf; |
282 | 288 |
283 create_breakpoint (python_gdbarch, | 289 create_breakpoint (python_gdbarch, |
284 addr_str, NULL, thread, | 290 addr_str, NULL, thread, NULL, |
285 0, | 291 0, |
286 1 /*temp_flag*/, | 292 1 /*temp_flag*/, |
287 bp_breakpoint, | 293 bp_breakpoint, |
288 0, | 294 0, |
289 AUTO_BOOLEAN_TRUE, | 295 AUTO_BOOLEAN_TRUE, |
290 &bkpt_breakpoint_ops, | 296 &bkpt_breakpoint_ops, |
291 0, 1, internal_bp, 0); | 297 0, 1, internal_bp, 0); |
292 } | 298 } |
293 GDB_PY_SET_HANDLE_EXCEPTION (except); | 299 GDB_PY_SET_HANDLE_EXCEPTION (except); |
294 | 300 |
(...skipping 11 matching lines...) Expand all Loading... |
306 return -1; | 312 return -1; |
307 } | 313 } |
308 | 314 |
309 /* Called when GDB notices that the finish breakpoint BP_OBJ is out of | 315 /* Called when GDB notices that the finish breakpoint BP_OBJ is out of |
310 the current callstack. Triggers the method OUT_OF_SCOPE if implemented, | 316 the current callstack. Triggers the method OUT_OF_SCOPE if implemented, |
311 then delete the breakpoint. */ | 317 then delete the breakpoint. */ |
312 | 318 |
313 static void | 319 static void |
314 bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj) | 320 bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj) |
315 { | 321 { |
316 volatile struct gdb_exception except; | |
317 breakpoint_object *bp_obj = (breakpoint_object *) bpfinish_obj; | 322 breakpoint_object *bp_obj = (breakpoint_object *) bpfinish_obj; |
318 PyObject *py_obj = (PyObject *) bp_obj; | 323 PyObject *py_obj = (PyObject *) bp_obj; |
319 | 324 |
320 if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled | 325 if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled |
321 && PyObject_HasAttrString (py_obj, outofscope_func)) | 326 && PyObject_HasAttrString (py_obj, outofscope_func)) |
322 { | 327 { |
323 if (!PyObject_CallMethod (py_obj, outofscope_func, NULL)) | 328 if (!PyObject_CallMethod (py_obj, outofscope_func, NULL)) |
324 gdbpy_print_stack (); | 329 gdbpy_print_stack (); |
325 } | 330 } |
326 | 331 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 finish_breakpoint_object_getset,/* tp_getset */ | 458 finish_breakpoint_object_getset,/* tp_getset */ |
454 &breakpoint_object_type, /* tp_base */ | 459 &breakpoint_object_type, /* tp_base */ |
455 0, /* tp_dict */ | 460 0, /* tp_dict */ |
456 0, /* tp_descr_get */ | 461 0, /* tp_descr_get */ |
457 0, /* tp_descr_set */ | 462 0, /* tp_descr_set */ |
458 0, /* tp_dictoffset */ | 463 0, /* tp_dictoffset */ |
459 bpfinishpy_init, /* tp_init */ | 464 bpfinishpy_init, /* tp_init */ |
460 0, /* tp_alloc */ | 465 0, /* tp_alloc */ |
461 0 /* tp_new */ | 466 0 /* tp_new */ |
462 }; | 467 }; |
OLD | NEW |