]> Git Repo - binutils.git/blob - gdb/python/py-finishbreakpoint.c
Remove redundant include directives.
[binutils.git] / gdb / python / py-finishbreakpoint.c
1 /* Python interface to finish breakpoints
2
3    Copyright (C) 2011-2015 Free Software Foundation, Inc.
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
20
21
22 #include "defs.h"
23 #include "python-internal.h"
24 #include "breakpoint.h"
25 #include "frame.h"
26 #include "gdbthread.h"
27 #include "arch-utils.h"
28 #include "language.h"
29 #include "observer.h"
30 #include "inferior.h"
31 #include "block.h"
32
33 /* Function that is called when a Python finish bp is found out of scope.  */
34 static char * const outofscope_func = "out_of_scope";
35
36 /* struct implementing the gdb.FinishBreakpoint object by extending
37    the gdb.Breakpoint class.  */
38 struct finish_breakpoint_object
39 {
40   /* gdb.Breakpoint base class.  */
41   gdbpy_breakpoint_object py_bp;
42   /* gdb.Type object of the value return by the breakpointed function.
43      May be NULL if no debug information was available or return type
44      was VOID.  */
45   PyObject *return_type;
46   /* gdb.Value object of the function finished by this breakpoint.  Will be
47      NULL if return_type is NULL.  */
48   PyObject *function_value;
49   /* When stopped at this FinishBreakpoint, gdb.Value object returned by
50      the function; Py_None if the value is not computable; NULL if GDB is
51      not stopped at a FinishBreakpoint.  */
52   PyObject *return_value;
53 };
54
55 extern PyTypeObject finish_breakpoint_object_type
56     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("finish_breakpoint_object");
57
58 /* Python function to get the 'return_value' attribute of
59    FinishBreakpoint.  */
60
61 static PyObject *
62 bpfinishpy_get_returnvalue (PyObject *self, void *closure)
63 {
64   struct finish_breakpoint_object *self_finishbp =
65       (struct finish_breakpoint_object *) self;
66
67   if (!self_finishbp->return_value)
68     Py_RETURN_NONE;
69
70   Py_INCREF (self_finishbp->return_value);
71   return self_finishbp->return_value;
72 }
73
74 /* Deallocate FinishBreakpoint object.  */
75
76 static void
77 bpfinishpy_dealloc (PyObject *self)
78 {
79   struct finish_breakpoint_object *self_bpfinish =
80         (struct finish_breakpoint_object *) self;
81
82   Py_XDECREF (self_bpfinish->function_value);
83   Py_XDECREF (self_bpfinish->return_type);
84   Py_XDECREF (self_bpfinish->return_value);
85 }
86
87 /* Triggered when gdbpy_should_stop is about to execute the `stop' callback
88    of the gdb.FinishBreakpoint object BP_OBJ.  Will compute and cache the
89    `return_value', if possible.  */
90
91 void
92 bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj)
93 {
94   struct finish_breakpoint_object *self_finishbp =
95         (struct finish_breakpoint_object *) bp_obj;
96
97   /* Can compute return_value only once.  */
98   gdb_assert (!self_finishbp->return_value);
99
100   if (!self_finishbp->return_type)
101     return;
102
103   TRY
104     {
105       struct value *function =
106         value_object_to_value (self_finishbp->function_value);
107       struct type *value_type =
108         type_object_to_type (self_finishbp->return_type);
109
110       /* bpfinishpy_init cannot finish into DUMMY_FRAME (throws an error
111          in such case) so it is OK to always pass CTX_SAVER as NULL.  */
112       struct value *ret = get_return_value (function, value_type, NULL);
113
114       if (ret)
115         {
116           self_finishbp->return_value = value_to_value_object (ret);
117           if (!self_finishbp->return_value)
118               gdbpy_print_stack ();
119         }
120       else
121         {
122           Py_INCREF (Py_None);
123           self_finishbp->return_value = Py_None;
124         }
125     }
126   CATCH (except, RETURN_MASK_ALL)
127     {
128       gdbpy_convert_exception (except);
129       gdbpy_print_stack ();
130     }
131   END_CATCH
132 }
133
134 /* Triggered when gdbpy_should_stop has triggered the `stop' callback
135    of the gdb.FinishBreakpoint object BP_OBJ.  */
136
137 void
138 bpfinishpy_post_stop_hook (struct gdbpy_breakpoint_object *bp_obj)
139 {
140
141   TRY
142     {
143       /* Can't delete it here, but it will be removed at the next stop.  */
144       disable_breakpoint (bp_obj->bp);
145       gdb_assert (bp_obj->bp->disposition == disp_del);
146     }
147   CATCH (except, RETURN_MASK_ALL)
148     {
149       gdbpy_convert_exception (except);
150       gdbpy_print_stack ();
151     }
152   END_CATCH
153 }
154
155 /* Python function to create a new breakpoint.  */
156
157 static int
158 bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
159 {
160   static char *keywords[] = { "frame", "internal", NULL };
161   struct finish_breakpoint_object *self_bpfinish =
162       (struct finish_breakpoint_object *) self;
163   int type = bp_breakpoint;
164   PyObject *frame_obj = NULL;
165   int thread;
166   struct frame_info *frame = NULL; /* init for gcc -Wall */
167   struct frame_info *prev_frame = NULL;
168   struct frame_id frame_id;
169   PyObject *internal = NULL;
170   int internal_bp = 0;
171   CORE_ADDR finish_pc, pc;
172   char *addr_str, small_buf[100];
173   struct symbol *function;
174
175   if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords,
176                                     &frame_obj, &internal))
177     return -1;
178
179   TRY
180     {
181       /* Default frame to newest frame if necessary.  */
182       if (frame_obj == NULL)
183         frame = get_current_frame ();
184       else
185         frame = frame_object_to_frame_info (frame_obj);
186
187       if (frame == NULL)
188         {
189           PyErr_SetString (PyExc_ValueError,
190                            _("Invalid ID for the `frame' object."));
191         }
192       else
193         {
194           prev_frame = get_prev_frame (frame);
195           if (prev_frame == 0)
196             {
197               PyErr_SetString (PyExc_ValueError,
198                                _("\"FinishBreakpoint\" not "
199                                  "meaningful in the outermost "
200                                  "frame."));
201             }
202           else if (get_frame_type (prev_frame) == DUMMY_FRAME)
203             {
204               PyErr_SetString (PyExc_ValueError,
205                                _("\"FinishBreakpoint\" cannot "
206                                  "be set on a dummy frame."));
207             }
208           else
209             {
210               frame_id = get_frame_id (prev_frame);
211               if (frame_id_eq (frame_id, null_frame_id))
212                 PyErr_SetString (PyExc_ValueError,
213                                  _("Invalid ID for the `frame' object."));
214             }
215         }
216     }
217   CATCH (except, RETURN_MASK_ALL)
218     {
219       gdbpy_convert_exception (except);
220       return -1;
221     }
222   END_CATCH
223
224   if (PyErr_Occurred ())
225     return -1;
226
227   thread = pid_to_thread_id (inferior_ptid);
228   if (thread == 0)
229     {
230       PyErr_SetString (PyExc_ValueError,
231                        _("No thread currently selected."));
232       return -1;
233     }
234
235   if (internal)
236     {
237       internal_bp = PyObject_IsTrue (internal);
238       if (internal_bp == -1)
239         {
240           PyErr_SetString (PyExc_ValueError,
241                            _("The value of `internal' must be a boolean."));
242           return -1;
243         }
244     }
245
246   /* Find the function we will return from.  */
247   self_bpfinish->return_type = NULL;
248   self_bpfinish->function_value = NULL;
249
250   TRY
251     {
252       if (get_frame_pc_if_available (frame, &pc))
253         {
254           function = find_pc_function (pc);
255           if (function != NULL)
256             {
257               struct type *ret_type =
258                   TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
259
260               /* Remember only non-void return types.  */
261               if (TYPE_CODE (ret_type) != TYPE_CODE_VOID)
262                 {
263                   struct value *func_value;
264
265                   /* Ignore Python errors at this stage.  */
266                   self_bpfinish->return_type = type_to_type_object (ret_type);
267                   PyErr_Clear ();
268                   func_value = read_var_value (function, frame);
269                   self_bpfinish->function_value =
270                       value_to_value_object (func_value);
271                   PyErr_Clear ();
272                 }
273             }
274         }
275     }
276   CATCH (except, RETURN_MASK_ALL)
277     {
278       /* Just swallow.  Either the return type or the function value
279          remain NULL.  */
280     }
281   END_CATCH
282
283   if (self_bpfinish->return_type == NULL || self_bpfinish->function_value == NULL)
284     {
285       /* Won't be able to compute return value.  */
286       Py_XDECREF (self_bpfinish->return_type);
287       Py_XDECREF (self_bpfinish->function_value);
288
289       self_bpfinish->return_type = NULL;
290       self_bpfinish->function_value = NULL;
291     }
292
293   bppy_pending_object = &self_bpfinish->py_bp;
294   bppy_pending_object->number = -1;
295   bppy_pending_object->bp = NULL;
296
297   TRY
298     {
299       /* Set a breakpoint on the return address.  */
300       finish_pc = get_frame_pc (prev_frame);
301       xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (finish_pc));
302       addr_str = small_buf;
303
304       create_breakpoint (python_gdbarch,
305                          addr_str, NULL, thread, NULL,
306                          0,
307                          1 /*temp_flag*/,
308                          bp_breakpoint,
309                          0,
310                          AUTO_BOOLEAN_TRUE,
311                          &bkpt_breakpoint_ops,
312                          0, 1, internal_bp, 0);
313     }
314   CATCH (except, RETURN_MASK_ALL)
315     {
316       GDB_PY_SET_HANDLE_EXCEPTION (except);
317     }
318   END_CATCH
319
320   self_bpfinish->py_bp.bp->frame_id = frame_id;
321   self_bpfinish->py_bp.is_finish_bp = 1;
322
323   /* Bind the breakpoint with the current program space.  */
324   self_bpfinish->py_bp.bp->pspace = current_program_space;
325
326   return 0;
327 }
328
329 /* Called when GDB notices that the finish breakpoint BP_OBJ is out of
330    the current callstack.  Triggers the method OUT_OF_SCOPE if implemented,
331    then delete the breakpoint.  */
332
333 static void
334 bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj)
335 {
336   gdbpy_breakpoint_object *bp_obj = (gdbpy_breakpoint_object *) bpfinish_obj;
337   PyObject *py_obj = (PyObject *) bp_obj;
338
339   if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled
340       && PyObject_HasAttrString (py_obj, outofscope_func))
341     {
342       PyObject *meth_result;
343
344       meth_result = PyObject_CallMethod (py_obj, outofscope_func, NULL);
345       if (meth_result == NULL)
346         gdbpy_print_stack ();
347       Py_XDECREF (meth_result);
348     }
349
350   delete_breakpoint (bpfinish_obj->py_bp.bp);
351 }
352
353 /* Callback for `bpfinishpy_detect_out_scope'.  Triggers Python's
354    `B->out_of_scope' function if B is a FinishBreakpoint out of its scope.  */
355
356 static int
357 bpfinishpy_detect_out_scope_cb (struct breakpoint *b, void *args)
358 {
359   struct breakpoint *bp_stopped = (struct breakpoint *) args;
360   PyObject *py_bp = (PyObject *) b->py_bp_object;
361   struct gdbarch *garch = b->gdbarch ? b->gdbarch : get_current_arch ();
362
363   /* Trigger out_of_scope if this is a FinishBreakpoint and its frame is
364      not anymore in the current callstack.  */
365   if (py_bp != NULL && b->py_bp_object->is_finish_bp)
366     {
367       struct finish_breakpoint_object *finish_bp =
368           (struct finish_breakpoint_object *) py_bp;
369
370       /* Check scope if not currently stopped at the FinishBreakpoint.  */
371       if (b != bp_stopped)
372         {
373           TRY
374             {
375               if (b->pspace == current_inferior ()->pspace
376                   && (!target_has_registers
377                       || frame_find_by_id (b->frame_id) == NULL))
378                 bpfinishpy_out_of_scope (finish_bp);
379             }
380           CATCH (except, RETURN_MASK_ALL)
381             {
382               gdbpy_convert_exception (except);
383               gdbpy_print_stack ();
384             }
385           END_CATCH
386         }
387     }
388
389   return 0;
390 }
391
392 /* Attached to `stop' notifications, check if the execution has run
393    out of the scope of any FinishBreakpoint before it has been hit.  */
394
395 static void
396 bpfinishpy_handle_stop (struct bpstats *bs, int print_frame)
397 {
398   struct cleanup *cleanup = ensure_python_env (get_current_arch (),
399                                                current_language);
400
401   iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb,
402                             bs == NULL ? NULL : bs->breakpoint_at);
403
404   do_cleanups (cleanup);
405 }
406
407 /* Attached to `exit' notifications, triggers all the necessary out of
408    scope notifications.  */
409
410 static void
411 bpfinishpy_handle_exit (struct inferior *inf)
412 {
413   struct cleanup *cleanup = ensure_python_env (target_gdbarch (),
414                                                current_language);
415
416   iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb, NULL);
417
418   do_cleanups (cleanup);
419 }
420
421 /* Initialize the Python finish breakpoint code.  */
422
423 int
424 gdbpy_initialize_finishbreakpoints (void)
425 {
426   if (PyType_Ready (&finish_breakpoint_object_type) < 0)
427     return -1;
428
429   if (gdb_pymodule_addobject (gdb_module, "FinishBreakpoint",
430                               (PyObject *) &finish_breakpoint_object_type) < 0)
431     return -1;
432
433   observer_attach_normal_stop (bpfinishpy_handle_stop);
434   observer_attach_inferior_exit (bpfinishpy_handle_exit);
435
436   return 0;
437 }
438
439 static PyGetSetDef finish_breakpoint_object_getset[] = {
440   { "return_value", bpfinishpy_get_returnvalue, NULL,
441   "gdb.Value object representing the return value, if any. \
442 None otherwise.", NULL },
443     { NULL }  /* Sentinel.  */
444 };
445
446 PyTypeObject finish_breakpoint_object_type =
447 {
448   PyVarObject_HEAD_INIT (NULL, 0)
449   "gdb.FinishBreakpoint",         /*tp_name*/
450   sizeof (struct finish_breakpoint_object),  /*tp_basicsize*/
451   0,                              /*tp_itemsize*/
452   bpfinishpy_dealloc,             /*tp_dealloc*/
453   0,                              /*tp_print*/
454   0,                              /*tp_getattr*/
455   0,                              /*tp_setattr*/
456   0,                              /*tp_compare*/
457   0,                              /*tp_repr*/
458   0,                              /*tp_as_number*/
459   0,                              /*tp_as_sequence*/
460   0,                              /*tp_as_mapping*/
461   0,                              /*tp_hash */
462   0,                              /*tp_call*/
463   0,                              /*tp_str*/
464   0,                              /*tp_getattro*/
465   0,                              /*tp_setattro */
466   0,                              /*tp_as_buffer*/
467   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
468   "GDB finish breakpoint object", /* tp_doc */
469   0,                              /* tp_traverse */
470   0,                              /* tp_clear */
471   0,                              /* tp_richcompare */
472   0,                              /* tp_weaklistoffset */
473   0,                              /* tp_iter */
474   0,                              /* tp_iternext */
475   0,                              /* tp_methods */
476   0,                              /* tp_members */
477   finish_breakpoint_object_getset,/* tp_getset */
478   &breakpoint_object_type,        /* tp_base */
479   0,                              /* tp_dict */
480   0,                              /* tp_descr_get */
481   0,                              /* tp_descr_set */
482   0,                              /* tp_dictoffset */
483   bpfinishpy_init,                /* tp_init */
484   0,                              /* tp_alloc */
485   0                               /* tp_new */
486 };
This page took 0.052739 seconds and 4 git commands to generate.