| 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 |