1 1.1 christos /* Scheme interface to stack frames. 2 1.1 christos 3 1.9 christos Copyright (C) 2008-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos /* See README file in this directory for implementation notes, coding 21 1.1 christos conventions, et.al. */ 22 1.1 christos 23 1.1 christos #include "block.h" 24 1.1 christos #include "frame.h" 25 1.1 christos #include "inferior.h" 26 1.1 christos #include "objfiles.h" 27 1.1 christos #include "symfile.h" 28 1.1 christos #include "symtab.h" 29 1.1 christos #include "stack.h" 30 1.3 christos #include "user-regs.h" 31 1.1 christos #include "value.h" 32 1.1 christos #include "guile-internal.h" 33 1.1 christos 34 1.8 christos /* The <gdb:frame> smob. */ 35 1.1 christos 36 1.8 christos struct frame_smob 37 1.1 christos { 38 1.1 christos /* This always appears first. */ 39 1.1 christos eqable_gdb_smob base; 40 1.1 christos 41 1.1 christos struct frame_id frame_id; 42 1.1 christos struct gdbarch *gdbarch; 43 1.1 christos 44 1.1 christos /* Frames are tracked by inferior. 45 1.1 christos We need some place to put the eq?-able hash table, and this feels as 46 1.1 christos good a place as any. Frames in one inferior shouldn't be considered 47 1.1 christos equal to frames in a different inferior. The frame becomes invalid if 48 1.1 christos this becomes NULL (the inferior has been deleted from gdb). 49 1.1 christos It's easier to relax restrictions than impose them after the fact. 50 1.1 christos N.B. It is an outstanding question whether a frame survives reruns of 51 1.1 christos the inferior. Intuitively the answer is "No", but currently a frame 52 1.1 christos also survives, e.g., multiple invocations of the same function from 53 1.1 christos the same point. Even different threads can have the same frame, e.g., 54 1.1 christos if a thread dies and a new thread gets the same stack. */ 55 1.1 christos struct inferior *inferior; 56 1.1 christos 57 1.1 christos /* Marks that the FRAME_ID member actually holds the ID of the frame next 58 1.1 christos to this, and not this frame's ID itself. This is a hack to permit Scheme 59 1.1 christos frame objects which represent invalid frames (i.e., the last frame_info 60 1.1 christos in a corrupt stack). The problem arises from the fact that this code 61 1.1 christos relies on FRAME_ID to uniquely identify a frame, which is not always true 62 1.1 christos for the last "frame" in a corrupt stack (it can have a null ID, or the 63 1.1 christos same ID as the previous frame). Whenever get_prev_frame returns NULL, we 64 1.1 christos record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */ 65 1.1 christos int frame_id_is_next; 66 1.1 christos }; 67 1.1 christos 68 1.1 christos static const char frame_smob_name[] = "gdb:frame"; 69 1.1 christos 70 1.1 christos /* The tag Guile knows the frame smob by. */ 71 1.1 christos static scm_t_bits frame_smob_tag; 72 1.1 christos 73 1.1 christos /* Keywords used in argument passing. */ 74 1.1 christos static SCM block_keyword; 75 1.1 christos 76 1.8 christos /* This is called when an inferior is about to be freed. 77 1.8 christos Invalidate the frame as further actions on the frame could result 78 1.8 christos in bad data. All access to the frame should be gated by 79 1.8 christos frscm_get_frame_smob_arg_unsafe which will raise an exception on 80 1.8 christos invalid frames. */ 81 1.8 christos struct frscm_deleter 82 1.8 christos { 83 1.8 christos /* Helper function for frscm_del_inferior_frames to mark the frame 84 1.8 christos as invalid. */ 85 1.8 christos 86 1.8 christos static int 87 1.8 christos frscm_mark_frame_invalid (void **slot, void *info) 88 1.8 christos { 89 1.8 christos frame_smob *f_smob = (frame_smob *) *slot; 90 1.8 christos 91 1.8 christos f_smob->inferior = NULL; 92 1.8 christos return 1; 93 1.8 christos } 94 1.8 christos 95 1.8 christos void operator() (htab_t htab) 96 1.8 christos { 97 1.8 christos gdb_assert (htab != nullptr); 98 1.8 christos htab_traverse_noresize (htab, frscm_mark_frame_invalid, NULL); 99 1.8 christos htab_delete (htab); 100 1.8 christos } 101 1.8 christos }; 102 1.8 christos 103 1.8 christos static const registry<inferior>::key<htab, frscm_deleter> 104 1.8 christos frscm_inferior_data_key; 105 1.1 christos 106 1.1 christos /* Administrivia for frame smobs. */ 108 1.1 christos 109 1.1 christos /* Helper function to hash a frame_smob. */ 110 1.1 christos 111 1.1 christos static hashval_t 112 1.1 christos frscm_hash_frame_smob (const void *p) 113 1.4 christos { 114 1.1 christos const frame_smob *f_smob = (const frame_smob *) p; 115 1.1 christos const struct frame_id *fid = &f_smob->frame_id; 116 1.1 christos hashval_t hash = htab_hash_pointer (f_smob->inferior); 117 1.1 christos 118 1.1 christos if (fid->stack_status == FID_STACK_VALID) 119 1.1 christos hash = iterative_hash (&fid->stack_addr, sizeof (fid->stack_addr), hash); 120 1.1 christos if (fid->code_addr_p) 121 1.1 christos hash = iterative_hash (&fid->code_addr, sizeof (fid->code_addr), hash); 122 1.1 christos if (fid->special_addr_p) 123 1.1 christos hash = iterative_hash (&fid->special_addr, sizeof (fid->special_addr), 124 1.1 christos hash); 125 1.1 christos 126 1.1 christos return hash; 127 1.1 christos } 128 1.1 christos 129 1.1 christos /* Helper function to compute equality of frame_smobs. */ 130 1.1 christos 131 1.1 christos static int 132 1.1 christos frscm_eq_frame_smob (const void *ap, const void *bp) 133 1.4 christos { 134 1.4 christos const frame_smob *a = (const frame_smob *) ap; 135 1.1 christos const frame_smob *b = (const frame_smob *) bp; 136 1.8 christos 137 1.1 christos return (a->frame_id == b->frame_id 138 1.1 christos && a->inferior == b->inferior 139 1.1 christos && a->inferior != NULL); 140 1.1 christos } 141 1.1 christos 142 1.1 christos /* Return the frame -> SCM mapping table. 143 1.1 christos It is created if necessary. */ 144 1.1 christos 145 1.1 christos static htab_t 146 1.1 christos frscm_inferior_frame_map (struct inferior *inferior) 147 1.8 christos { 148 1.1 christos htab_t htab = frscm_inferior_data_key.get (inferior); 149 1.1 christos 150 1.1 christos if (htab == NULL) 151 1.1 christos { 152 1.1 christos htab = gdbscm_create_eqable_gsmob_ptr_map (frscm_hash_frame_smob, 153 1.8 christos frscm_eq_frame_smob); 154 1.1 christos frscm_inferior_data_key.set (inferior, htab); 155 1.1 christos } 156 1.1 christos 157 1.1 christos return htab; 158 1.1 christos } 159 1.1 christos 160 1.1 christos /* The smob "free" function for <gdb:frame>. */ 161 1.1 christos 162 1.1 christos static size_t 163 1.1 christos frscm_free_frame_smob (SCM self) 164 1.1 christos { 165 1.1 christos frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self); 166 1.1 christos 167 1.1 christos if (f_smob->inferior != NULL) 168 1.1 christos { 169 1.1 christos htab_t htab = frscm_inferior_frame_map (f_smob->inferior); 170 1.1 christos 171 1.1 christos gdbscm_clear_eqable_gsmob_ptr_slot (htab, &f_smob->base); 172 1.1 christos } 173 1.1 christos 174 1.1 christos /* Not necessary, done to catch bugs. */ 175 1.1 christos f_smob->inferior = NULL; 176 1.1 christos 177 1.1 christos return 0; 178 1.1 christos } 179 1.1 christos 180 1.1 christos /* The smob "print" function for <gdb:frame>. */ 181 1.1 christos 182 1.1 christos static int 183 1.1 christos frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate) 184 1.1 christos { 185 1.1 christos frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self); 186 1.8 christos 187 1.8 christos gdbscm_printf (port, "#<%s %s>", 188 1.8 christos frame_smob_name, 189 1.1 christos f_smob->frame_id.to_string ().c_str ()); 190 1.1 christos scm_remember_upto_here_1 (self); 191 1.1 christos 192 1.1 christos /* Non-zero means success. */ 193 1.1 christos return 1; 194 1.1 christos } 195 1.1 christos 196 1.1 christos /* Low level routine to create a <gdb:frame> object. */ 197 1.1 christos 198 1.1 christos static SCM 199 1.1 christos frscm_make_frame_smob (void) 200 1.1 christos { 201 1.1 christos frame_smob *f_smob = (frame_smob *) 202 1.1 christos scm_gc_malloc (sizeof (frame_smob), frame_smob_name); 203 1.1 christos SCM f_scm; 204 1.1 christos 205 1.1 christos f_smob->frame_id = null_frame_id; 206 1.1 christos f_smob->gdbarch = NULL; 207 1.1 christos f_smob->inferior = NULL; 208 1.1 christos f_smob->frame_id_is_next = 0; 209 1.1 christos f_scm = scm_new_smob (frame_smob_tag, (scm_t_bits) f_smob); 210 1.1 christos gdbscm_init_eqable_gsmob (&f_smob->base, f_scm); 211 1.1 christos 212 1.1 christos return f_scm; 213 1.1 christos } 214 1.1 christos 215 1.1 christos /* Return non-zero if SCM is a <gdb:frame> object. */ 216 1.1 christos 217 1.1 christos int 218 1.1 christos frscm_is_frame (SCM scm) 219 1.1 christos { 220 1.1 christos return SCM_SMOB_PREDICATE (frame_smob_tag, scm); 221 1.1 christos } 222 1.1 christos 223 1.1 christos /* (frame? object) -> boolean */ 224 1.1 christos 225 1.1 christos static SCM 226 1.1 christos gdbscm_frame_p (SCM scm) 227 1.1 christos { 228 1.1 christos return scm_from_bool (frscm_is_frame (scm)); 229 1.1 christos } 230 1.1 christos 231 1.1 christos /* Create a new <gdb:frame> object that encapsulates FRAME. 232 1.1 christos Returns a <gdb:exception> object if there is an error. */ 233 1.1 christos 234 1.1 christos static SCM 235 1.1 christos frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior) 236 1.1 christos { 237 1.1 christos frame_smob *f_smob, f_smob_for_lookup; 238 1.1 christos SCM f_scm; 239 1.1 christos htab_t htab; 240 1.1 christos eqable_gdb_smob **slot; 241 1.1 christos struct frame_id frame_id = null_frame_id; 242 1.1 christos struct gdbarch *gdbarch = NULL; 243 1.1 christos int frame_id_is_next = 0; 244 1.1 christos 245 1.1 christos /* If we've already created a gsmob for this frame, return it. 246 1.1 christos This makes frames eq?-able. */ 247 1.8 christos htab = frscm_inferior_frame_map (inferior); 248 1.1 christos f_smob_for_lookup.frame_id = get_frame_id (frame_info_ptr (frame)); 249 1.1 christos f_smob_for_lookup.inferior = inferior; 250 1.1 christos slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &f_smob_for_lookup.base); 251 1.1 christos if (*slot != NULL) 252 1.1 christos return (*slot)->containing_scm; 253 1.7 christos 254 1.1 christos try 255 1.8 christos { 256 1.8 christos frame_info_ptr frame_ptr (frame); 257 1.1 christos 258 1.1 christos /* Try to get the previous frame, to determine if this is the last frame 259 1.1 christos in a corrupt stack. If so, we need to store the frame_id of the next 260 1.8 christos frame and not of this one (which is possibly invalid). */ 261 1.8 christos if (get_prev_frame (frame_ptr) == NULL 262 1.8 christos && get_frame_unwind_stop_reason (frame_ptr) != UNWIND_NO_REASON 263 1.1 christos && get_next_frame (frame_ptr) != NULL) 264 1.8 christos { 265 1.1 christos frame_id = get_frame_id (get_next_frame (frame_ptr)); 266 1.1 christos frame_id_is_next = 1; 267 1.1 christos } 268 1.1 christos else 269 1.8 christos { 270 1.1 christos frame_id = get_frame_id (frame_ptr); 271 1.1 christos frame_id_is_next = 0; 272 1.8 christos } 273 1.1 christos gdbarch = get_frame_arch (frame_ptr); 274 1.7 christos } 275 1.3 christos catch (const gdb_exception &except) 276 1.7 christos { 277 1.3 christos return gdbscm_scm_from_gdb_exception (unpack (except)); 278 1.1 christos } 279 1.1 christos 280 1.1 christos f_scm = frscm_make_frame_smob (); 281 1.1 christos f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm); 282 1.1 christos f_smob->frame_id = frame_id; 283 1.1 christos f_smob->gdbarch = gdbarch; 284 1.1 christos f_smob->inferior = inferior; 285 1.1 christos f_smob->frame_id_is_next = frame_id_is_next; 286 1.1 christos 287 1.1 christos gdbscm_fill_eqable_gsmob_ptr_slot (slot, &f_smob->base); 288 1.1 christos 289 1.1 christos return f_scm; 290 1.1 christos } 291 1.1 christos 292 1.1 christos /* Create a new <gdb:frame> object that encapsulates FRAME. 293 1.1 christos A Scheme exception is thrown if there is an error. */ 294 1.1 christos 295 1.1 christos static SCM 296 1.1 christos frscm_scm_from_frame_unsafe (struct frame_info *frame, 297 1.1 christos struct inferior *inferior) 298 1.1 christos { 299 1.1 christos SCM f_scm = frscm_scm_from_frame (frame, inferior); 300 1.1 christos 301 1.1 christos if (gdbscm_is_exception (f_scm)) 302 1.1 christos gdbscm_throw (f_scm); 303 1.1 christos 304 1.1 christos return f_scm; 305 1.1 christos } 306 1.1 christos 307 1.1 christos /* Returns the <gdb:frame> object in SELF. 308 1.1 christos Throws an exception if SELF is not a <gdb:frame> object. */ 309 1.1 christos 310 1.1 christos static SCM 311 1.1 christos frscm_get_frame_arg_unsafe (SCM self, int arg_pos, const char *func_name) 312 1.1 christos { 313 1.1 christos SCM_ASSERT_TYPE (frscm_is_frame (self), self, arg_pos, func_name, 314 1.1 christos frame_smob_name); 315 1.1 christos 316 1.1 christos return self; 317 1.1 christos } 318 1.1 christos 319 1.1 christos /* There is no gdbscm_scm_to_frame function because translating 320 1.1 christos a frame SCM object to a struct frame_info * can throw a GDB error. 321 1.1 christos Thus code working with frames has to handle both Scheme errors (e.g., the 322 1.1 christos object is not a frame) and GDB errors (e.g., the frame lookup failed). 323 1.3 christos 324 1.3 christos To help keep things clear we split what would be gdbscm_scm_to_frame 325 1.1 christos into two: 326 1.3 christos 327 1.1 christos frscm_get_frame_smob_arg_unsafe 328 1.1 christos - throws a Scheme error if object is not a frame, 329 1.1 christos or if the inferior is gone or is no longer current 330 1.3 christos 331 1.1 christos frscm_frame_smob_to_frame 332 1.1 christos - may throw a gdb error if the conversion fails 333 1.1 christos - it's not clear when it will and won't throw a GDB error, 334 1.1 christos but for robustness' sake we assume that whenever we call out to GDB 335 1.1 christos a GDB error may get thrown (and thus the call must be wrapped in a 336 1.1 christos TRY_CATCH) */ 337 1.1 christos 338 1.1 christos /* Returns the frame_smob for the object wrapped by FRAME_SCM. 339 1.1 christos A Scheme error is thrown if FRAME_SCM is not a frame. */ 340 1.1 christos 341 1.1 christos frame_smob * 342 1.1 christos frscm_get_frame_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name) 343 1.1 christos { 344 1.1 christos SCM f_scm = frscm_get_frame_arg_unsafe (self, arg_pos, func_name); 345 1.1 christos frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm); 346 1.1 christos 347 1.1 christos if (f_smob->inferior == NULL) 348 1.1 christos { 349 1.1 christos gdbscm_invalid_object_error (func_name, arg_pos, self, 350 1.1 christos _("inferior")); 351 1.1 christos } 352 1.1 christos if (f_smob->inferior != current_inferior ()) 353 1.1 christos scm_misc_error (func_name, _("inferior has changed"), SCM_EOL); 354 1.1 christos 355 1.1 christos return f_smob; 356 1.1 christos } 357 1.1 christos 358 1.1 christos /* Returns the frame_info object wrapped by F_SMOB. 359 1.1 christos If the frame doesn't exist anymore (the frame id doesn't 360 1.1 christos correspond to any frame in the inferior), returns NULL. 361 1.1 christos This function calls GDB routines, so don't assume a GDB error will 362 1.1 christos not be thrown. */ 363 1.8 christos 364 1.1 christos struct frame_info_ptr 365 1.1 christos frscm_frame_smob_to_frame (frame_smob *f_smob) 366 1.8 christos { 367 1.1 christos frame_info_ptr frame = frame_find_by_id (f_smob->frame_id); 368 1.1 christos if (frame == NULL) 369 1.1 christos return NULL; 370 1.1 christos 371 1.1 christos if (f_smob->frame_id_is_next) 372 1.1 christos frame = get_prev_frame (frame); 373 1.1 christos 374 1.1 christos return frame; 375 1.1 christos } 376 1.1 christos 377 1.1 christos 378 1.1 christos /* Frame methods. */ 380 1.1 christos 381 1.1 christos /* (frame-valid? <gdb:frame>) -> bool 382 1.1 christos Returns #t if the frame corresponding to the frame_id of this 383 1.1 christos object still exists in the inferior. */ 384 1.1 christos 385 1.1 christos static SCM 386 1.1 christos gdbscm_frame_valid_p (SCM self) 387 1.8 christos { 388 1.1 christos frame_smob *f_smob; 389 1.1 christos bool result = false; 390 1.1 christos 391 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 392 1.7 christos 393 1.1 christos gdbscm_gdb_exception exc {}; 394 1.8 christos try 395 1.8 christos { 396 1.1 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 397 1.7 christos result = frame != nullptr; 398 1.3 christos } 399 1.7 christos catch (const gdb_exception &except) 400 1.3 christos { 401 1.1 christos exc = unpack (except); 402 1.7 christos } 403 1.8 christos 404 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 405 1.1 christos return scm_from_bool (result); 406 1.1 christos } 407 1.1 christos 408 1.1 christos /* (frame-name <gdb:frame>) -> string 409 1.1 christos Returns the name of the function corresponding to this frame, 410 1.1 christos or #f if there is no function. */ 411 1.1 christos 412 1.1 christos static SCM 413 1.1 christos gdbscm_frame_name (SCM self) 414 1.6 christos { 415 1.1 christos frame_smob *f_smob; 416 1.8 christos gdb::unique_xmalloc_ptr<char> name; 417 1.1 christos enum language lang = language_minimal; 418 1.1 christos bool found = false; 419 1.1 christos SCM result; 420 1.1 christos 421 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 422 1.7 christos 423 1.1 christos gdbscm_gdb_exception exc {}; 424 1.8 christos try 425 1.1 christos { 426 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 427 1.8 christos if (frame != NULL) 428 1.8 christos { 429 1.8 christos found = true; 430 1.1 christos name = find_frame_funname (frame, &lang, NULL); 431 1.7 christos } 432 1.3 christos } 433 1.7 christos catch (const gdb_exception &except) 434 1.3 christos { 435 1.1 christos exc = unpack (except); 436 1.7 christos } 437 1.8 christos 438 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 439 1.1 christos if (!found) 440 1.1 christos { 441 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 442 1.1 christos _("<gdb:frame>")); 443 1.1 christos } 444 1.6 christos 445 1.1 christos if (name != NULL) 446 1.1 christos result = gdbscm_scm_from_c_string (name.get ()); 447 1.1 christos else 448 1.1 christos result = SCM_BOOL_F; 449 1.1 christos 450 1.1 christos return result; 451 1.1 christos } 452 1.1 christos 453 1.1 christos /* (frame-type <gdb:frame>) -> integer 454 1.1 christos Returns the frame type, namely one of the gdb:*_FRAME constants. */ 455 1.1 christos 456 1.1 christos static SCM 457 1.1 christos gdbscm_frame_type (SCM self) 458 1.1 christos { 459 1.8 christos frame_smob *f_smob; 460 1.1 christos enum frame_type type = NORMAL_FRAME; 461 1.1 christos bool found = false; 462 1.1 christos 463 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 464 1.7 christos 465 1.1 christos gdbscm_gdb_exception exc {}; 466 1.8 christos try 467 1.1 christos { 468 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 469 1.8 christos if (frame != NULL) 470 1.8 christos { 471 1.8 christos found = true; 472 1.1 christos type = get_frame_type (frame); 473 1.7 christos } 474 1.3 christos } 475 1.7 christos catch (const gdb_exception &except) 476 1.3 christos { 477 1.1 christos exc = unpack (except); 478 1.7 christos } 479 1.8 christos 480 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 481 1.1 christos if (!found) 482 1.1 christos { 483 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 484 1.1 christos _("<gdb:frame>")); 485 1.1 christos } 486 1.1 christos 487 1.1 christos return scm_from_int (type); 488 1.1 christos } 489 1.1 christos 490 1.1 christos /* (frame-arch <gdb:frame>) -> <gdb:architecture> 491 1.1 christos Returns the frame's architecture as a gdb:architecture object. */ 492 1.1 christos 493 1.1 christos static SCM 494 1.1 christos gdbscm_frame_arch (SCM self) 495 1.8 christos { 496 1.1 christos frame_smob *f_smob; 497 1.1 christos bool found = false; 498 1.1 christos 499 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 500 1.7 christos 501 1.1 christos gdbscm_gdb_exception exc {}; 502 1.8 christos try 503 1.8 christos { 504 1.1 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 505 1.7 christos found = frame != nullptr; 506 1.3 christos } 507 1.7 christos catch (const gdb_exception &except) 508 1.3 christos { 509 1.1 christos exc = unpack (except); 510 1.7 christos } 511 1.8 christos 512 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 513 1.1 christos if (!found) 514 1.1 christos { 515 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 516 1.1 christos _("<gdb:frame>")); 517 1.1 christos } 518 1.1 christos 519 1.1 christos return arscm_scm_from_arch (f_smob->gdbarch); 520 1.1 christos } 521 1.1 christos 522 1.1 christos /* (frame-unwind-stop-reason <gdb:frame>) -> integer 523 1.1 christos Returns one of the gdb:FRAME_UNWIND_* constants. */ 524 1.1 christos 525 1.1 christos static SCM 526 1.1 christos gdbscm_frame_unwind_stop_reason (SCM self) 527 1.8 christos { 528 1.8 christos frame_smob *f_smob; 529 1.1 christos bool found = false; 530 1.1 christos enum unwind_stop_reason stop_reason = UNWIND_NO_REASON; 531 1.1 christos 532 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 533 1.7 christos 534 1.1 christos gdbscm_gdb_exception exc {}; 535 1.8 christos try 536 1.8 christos { 537 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 538 1.8 christos if (frame != nullptr) 539 1.8 christos { 540 1.8 christos found = true; 541 1.1 christos stop_reason = get_frame_unwind_stop_reason (frame); 542 1.7 christos } 543 1.3 christos } 544 1.7 christos catch (const gdb_exception &except) 545 1.3 christos { 546 1.1 christos exc = unpack (except); 547 1.7 christos } 548 1.8 christos 549 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 550 1.1 christos if (!found) 551 1.1 christos { 552 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 553 1.1 christos _("<gdb:frame>")); 554 1.1 christos } 555 1.1 christos 556 1.1 christos return scm_from_int (stop_reason); 557 1.1 christos } 558 1.1 christos 559 1.1 christos /* (frame-pc <gdb:frame>) -> integer 560 1.1 christos Returns the frame's resume address. */ 561 1.1 christos 562 1.1 christos static SCM 563 1.1 christos gdbscm_frame_pc (SCM self) 564 1.1 christos { 565 1.8 christos frame_smob *f_smob; 566 1.1 christos CORE_ADDR pc = 0; 567 1.1 christos bool found = false; 568 1.1 christos 569 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 570 1.7 christos 571 1.1 christos gdbscm_gdb_exception exc {}; 572 1.8 christos try 573 1.1 christos { 574 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 575 1.8 christos if (frame != NULL) 576 1.8 christos { 577 1.8 christos pc = get_frame_pc (frame); 578 1.1 christos found = true; 579 1.7 christos } 580 1.3 christos } 581 1.7 christos catch (const gdb_exception &except) 582 1.3 christos { 583 1.1 christos exc = unpack (except); 584 1.7 christos } 585 1.8 christos 586 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 587 1.1 christos if (!found) 588 1.1 christos { 589 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 590 1.1 christos _("<gdb:frame>")); 591 1.1 christos } 592 1.1 christos 593 1.1 christos return gdbscm_scm_from_ulongest (pc); 594 1.1 christos } 595 1.1 christos 596 1.1 christos /* (frame-block <gdb:frame>) -> <gdb:block> 597 1.1 christos Returns the frame's code block, or #f if one cannot be found. */ 598 1.1 christos 599 1.1 christos static SCM 600 1.1 christos gdbscm_frame_block (SCM self) 601 1.1 christos { 602 1.8 christos frame_smob *f_smob; 603 1.1 christos const struct block *block = NULL, *fn_block; 604 1.1 christos bool found = false; 605 1.1 christos 606 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 607 1.7 christos 608 1.1 christos gdbscm_gdb_exception exc {}; 609 1.8 christos try 610 1.1 christos { 611 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 612 1.8 christos if (frame != NULL) 613 1.8 christos { 614 1.8 christos found = true; 615 1.1 christos block = get_frame_block (frame, NULL); 616 1.7 christos } 617 1.3 christos } 618 1.7 christos catch (const gdb_exception &except) 619 1.3 christos { 620 1.1 christos exc = unpack (except); 621 1.7 christos } 622 1.8 christos 623 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 624 1.1 christos if (!found) 625 1.1 christos { 626 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 627 1.1 christos _("<gdb:frame>")); 628 1.1 christos } 629 1.8 christos 630 1.8 christos for (fn_block = block; 631 1.1 christos fn_block != NULL && fn_block->function () == NULL; 632 1.1 christos fn_block = fn_block->superblock ()) 633 1.8 christos continue; 634 1.1 christos 635 1.1 christos if (block == NULL || fn_block == NULL || fn_block->function () == NULL) 636 1.1 christos { 637 1.1 christos scm_misc_error (FUNC_NAME, _("cannot find block for frame"), 638 1.1 christos scm_list_1 (self)); 639 1.1 christos } 640 1.1 christos 641 1.1 christos if (block != NULL) 642 1.8 christos { 643 1.1 christos return bkscm_scm_from_block 644 1.1 christos (block, fn_block->function ()->objfile ()); 645 1.1 christos } 646 1.1 christos 647 1.1 christos return SCM_BOOL_F; 648 1.1 christos } 649 1.1 christos 650 1.1 christos /* (frame-function <gdb:frame>) -> <gdb:symbol> 651 1.1 christos Returns the symbol for the function corresponding to this frame, 652 1.1 christos or #f if there isn't one. */ 653 1.1 christos 654 1.1 christos static SCM 655 1.1 christos gdbscm_frame_function (SCM self) 656 1.1 christos { 657 1.8 christos frame_smob *f_smob; 658 1.1 christos struct symbol *sym = NULL; 659 1.1 christos bool found = false; 660 1.1 christos 661 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 662 1.7 christos 663 1.1 christos gdbscm_gdb_exception exc {}; 664 1.8 christos try 665 1.1 christos { 666 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 667 1.8 christos if (frame != NULL) 668 1.8 christos { 669 1.8 christos found = true; 670 1.1 christos sym = find_pc_function (get_frame_address_in_block (frame)); 671 1.7 christos } 672 1.3 christos } 673 1.7 christos catch (const gdb_exception &except) 674 1.3 christos { 675 1.1 christos exc = unpack (except); 676 1.7 christos } 677 1.8 christos 678 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 679 1.1 christos if (!found) 680 1.1 christos { 681 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 682 1.1 christos _("<gdb:frame>")); 683 1.1 christos } 684 1.1 christos 685 1.1 christos if (sym != NULL) 686 1.1 christos return syscm_scm_from_symbol (sym); 687 1.1 christos 688 1.1 christos return SCM_BOOL_F; 689 1.1 christos } 690 1.1 christos 691 1.1 christos /* (frame-older <gdb:frame>) -> <gdb:frame> 692 1.1 christos Returns the frame immediately older (outer) to this frame, 693 1.1 christos or #f if there isn't one. */ 694 1.1 christos 695 1.1 christos static SCM 696 1.1 christos gdbscm_frame_older (SCM self) 697 1.1 christos { 698 1.8 christos frame_smob *f_smob; 699 1.1 christos struct frame_info *prev = NULL; 700 1.1 christos bool found = false; 701 1.1 christos 702 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 703 1.7 christos 704 1.1 christos gdbscm_gdb_exception exc {}; 705 1.8 christos try 706 1.1 christos { 707 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 708 1.8 christos if (frame != NULL) 709 1.8 christos { 710 1.8 christos found = true; 711 1.1 christos prev = get_prev_frame (frame).get (); 712 1.7 christos } 713 1.3 christos } 714 1.7 christos catch (const gdb_exception &except) 715 1.3 christos { 716 1.1 christos exc = unpack (except); 717 1.7 christos } 718 1.8 christos 719 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 720 1.1 christos if (!found) 721 1.1 christos { 722 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 723 1.1 christos _("<gdb:frame>")); 724 1.1 christos } 725 1.1 christos 726 1.1 christos if (prev != NULL) 727 1.1 christos return frscm_scm_from_frame_unsafe (prev, f_smob->inferior); 728 1.1 christos 729 1.1 christos return SCM_BOOL_F; 730 1.1 christos } 731 1.1 christos 732 1.1 christos /* (frame-newer <gdb:frame>) -> <gdb:frame> 733 1.1 christos Returns the frame immediately newer (inner) to this frame, 734 1.1 christos or #f if there isn't one. */ 735 1.1 christos 736 1.1 christos static SCM 737 1.1 christos gdbscm_frame_newer (SCM self) 738 1.1 christos { 739 1.8 christos frame_smob *f_smob; 740 1.1 christos struct frame_info *next = NULL; 741 1.1 christos bool found = false; 742 1.1 christos 743 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 744 1.7 christos 745 1.1 christos gdbscm_gdb_exception exc {}; 746 1.8 christos try 747 1.1 christos { 748 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 749 1.8 christos if (frame != NULL) 750 1.8 christos { 751 1.8 christos found = true; 752 1.1 christos next = get_next_frame (frame).get (); 753 1.7 christos } 754 1.3 christos } 755 1.7 christos catch (const gdb_exception &except) 756 1.3 christos { 757 1.1 christos exc = unpack (except); 758 1.7 christos } 759 1.8 christos 760 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 761 1.1 christos if (!found) 762 1.1 christos { 763 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 764 1.1 christos _("<gdb:frame>")); 765 1.1 christos } 766 1.1 christos 767 1.1 christos if (next != NULL) 768 1.1 christos return frscm_scm_from_frame_unsafe (next, f_smob->inferior); 769 1.1 christos 770 1.1 christos return SCM_BOOL_F; 771 1.1 christos } 772 1.1 christos 773 1.1 christos /* (frame-sal <gdb:frame>) -> <gdb:sal> 774 1.1 christos Returns the frame's symtab and line. */ 775 1.1 christos 776 1.1 christos static SCM 777 1.1 christos gdbscm_frame_sal (SCM self) 778 1.1 christos { 779 1.8 christos frame_smob *f_smob; 780 1.1 christos struct symtab_and_line sal; 781 1.1 christos bool found = false; 782 1.1 christos 783 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 784 1.7 christos 785 1.1 christos gdbscm_gdb_exception exc {}; 786 1.8 christos try 787 1.1 christos { 788 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 789 1.8 christos if (frame != NULL) 790 1.8 christos { 791 1.8 christos found = true; 792 1.1 christos sal = find_frame_sal (frame); 793 1.7 christos } 794 1.3 christos } 795 1.7 christos catch (const gdb_exception &except) 796 1.3 christos { 797 1.1 christos exc = unpack (except); 798 1.7 christos } 799 1.8 christos 800 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 801 1.1 christos if (!found) 802 1.1 christos { 803 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 804 1.1 christos _("<gdb:frame>")); 805 1.1 christos } 806 1.1 christos 807 1.1 christos return stscm_scm_from_sal (sal); 808 1.3 christos } 809 1.3 christos 810 1.3 christos /* (frame-read-register <gdb:frame> string) -> <gdb:value> 811 1.3 christos The register argument must be a string. */ 812 1.3 christos 813 1.3 christos static SCM 814 1.3 christos gdbscm_frame_read_register (SCM self, SCM register_scm) 815 1.3 christos { 816 1.8 christos char *register_str; 817 1.3 christos struct value *value = NULL; 818 1.3 christos bool found = false; 819 1.3 christos frame_smob *f_smob; 820 1.3 christos 821 1.3 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 822 1.6 christos gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "s", 823 1.7 christos register_scm, ®ister_str); 824 1.3 christos 825 1.7 christos gdbscm_gdb_exception except {}; 826 1.3 christos 827 1.3 christos try 828 1.3 christos { 829 1.8 christos int regnum; 830 1.3 christos 831 1.3 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 832 1.8 christos if (frame) 833 1.3 christos { 834 1.3 christos found = true; 835 1.3 christos regnum = user_reg_map_name_to_regnum (get_frame_arch (frame), 836 1.3 christos register_str, 837 1.9 christos strlen (register_str)); 838 1.9 christos if (regnum >= 0) 839 1.3 christos value = value_of_register (regnum, 840 1.3 christos get_next_frame_sentinel_okay (frame)); 841 1.7 christos } 842 1.3 christos } 843 1.7 christos catch (const gdb_exception &ex) 844 1.3 christos { 845 1.3 christos except = unpack (ex); 846 1.6 christos } 847 1.6 christos 848 1.3 christos xfree (register_str); 849 1.8 christos GDBSCM_HANDLE_GDB_EXCEPTION (except); 850 1.3 christos 851 1.3 christos if (!found) 852 1.3 christos { 853 1.3 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 854 1.3 christos _("<gdb:frame>")); 855 1.3 christos } 856 1.3 christos 857 1.3 christos if (value == NULL) 858 1.3 christos { 859 1.3 christos gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, register_scm, 860 1.3 christos _("unknown register")); 861 1.3 christos } 862 1.3 christos 863 1.3 christos return vlscm_scm_from_value (value); 864 1.1 christos } 865 1.1 christos 866 1.1 christos /* (frame-read-var <gdb:frame> <gdb:symbol>) -> <gdb:value> 867 1.1 christos (frame-read-var <gdb:frame> string [#:block <gdb:block>]) -> <gdb:value> 868 1.1 christos If the optional block argument is provided start the search from that block, 869 1.1 christos otherwise search from the frame's current block (determined by examining 870 1.1 christos the resume address of the frame). The variable argument must be a string 871 1.1 christos or an instance of a <gdb:symbol>. The block argument must be an instance of 872 1.1 christos <gdb:block>. */ 873 1.1 christos 874 1.1 christos static SCM 875 1.1 christos gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest) 876 1.1 christos { 877 1.1 christos SCM keywords[] = { block_keyword, SCM_BOOL_F }; 878 1.1 christos frame_smob *f_smob; 879 1.1 christos int block_arg_pos = -1; 880 1.1 christos SCM block_scm = SCM_UNDEFINED; 881 1.4 christos struct frame_info *frame = NULL; 882 1.1 christos struct symbol *var = NULL; 883 1.1 christos const struct block *block = NULL; 884 1.1 christos struct value *value = NULL; 885 1.1 christos 886 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 887 1.7 christos 888 1.1 christos gdbscm_gdb_exception exc {}; 889 1.8 christos try 890 1.1 christos { 891 1.7 christos frame = frscm_frame_smob_to_frame (f_smob).get (); 892 1.3 christos } 893 1.7 christos catch (const gdb_exception &except) 894 1.3 christos { 895 1.1 christos exc = unpack (except); 896 1.7 christos } 897 1.1 christos 898 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 899 1.1 christos if (frame == NULL) 900 1.1 christos { 901 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 902 1.1 christos _("<gdb:frame>")); 903 1.1 christos } 904 1.1 christos 905 1.1 christos gdbscm_parse_function_args (FUNC_NAME, SCM_ARG3, keywords, "#O", 906 1.1 christos rest, &block_arg_pos, &block_scm); 907 1.1 christos 908 1.1 christos if (syscm_is_symbol (symbol_scm)) 909 1.1 christos { 910 1.1 christos var = syscm_get_valid_symbol_arg_unsafe (symbol_scm, SCM_ARG2, 911 1.1 christos FUNC_NAME); 912 1.1 christos SCM_ASSERT (SCM_UNBNDP (block_scm), block_scm, SCM_ARG3, FUNC_NAME); 913 1.1 christos } 914 1.7 christos else if (scm_is_string (symbol_scm)) 915 1.1 christos { 916 1.1 christos gdbscm_gdb_exception except {}; 917 1.1 christos 918 1.1 christos if (! SCM_UNBNDP (block_scm)) 919 1.1 christos { 920 1.1 christos SCM except_scm; 921 1.1 christos 922 1.1 christos gdb_assert (block_arg_pos > 0); 923 1.1 christos block = bkscm_scm_to_block (block_scm, block_arg_pos, FUNC_NAME, 924 1.1 christos &except_scm); 925 1.1 christos if (block == NULL) 926 1.1 christos gdbscm_throw (except_scm); 927 1.6 christos } 928 1.6 christos 929 1.6 christos { 930 1.6 christos gdb::unique_xmalloc_ptr<char> var_name 931 1.6 christos (gdbscm_scm_to_c_string (symbol_scm)); 932 1.6 christos /* N.B. Between here and the end of the scope, don't do anything 933 1.7 christos to cause a Scheme exception. */ 934 1.6 christos 935 1.6 christos try 936 1.6 christos { 937 1.6 christos struct block_symbol lookup_sym; 938 1.8 christos 939 1.9 christos if (block == NULL) 940 1.6 christos block = get_frame_block (frame_info_ptr (frame), NULL); 941 1.6 christos lookup_sym = lookup_symbol (var_name.get (), block, SEARCH_VFT, 942 1.6 christos NULL); 943 1.6 christos var = lookup_sym.symbol; 944 1.7 christos block = lookup_sym.block; 945 1.6 christos } 946 1.7 christos catch (const gdb_exception &ex) 947 1.6 christos { 948 1.6 christos except = unpack (ex); 949 1.4 christos } 950 1.1 christos } 951 1.1 christos 952 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (except); 953 1.6 christos 954 1.6 christos if (var == NULL) 955 1.1 christos gdbscm_out_of_range_error (FUNC_NAME, 0, symbol_scm, 956 1.1 christos _("variable not found")); 957 1.1 christos } 958 1.1 christos else 959 1.1 christos { 960 1.1 christos /* Use SCM_ASSERT_TYPE for more consistent error messages. */ 961 1.1 christos SCM_ASSERT_TYPE (0, symbol_scm, SCM_ARG1, FUNC_NAME, 962 1.1 christos _("gdb:symbol or string")); 963 1.7 christos } 964 1.1 christos 965 1.8 christos try 966 1.1 christos { 967 1.7 christos value = read_var_value (var, block, frame_info_ptr (frame)); 968 1.3 christos } 969 1.7 christos catch (const gdb_exception &except) 970 1.3 christos { 971 1.1 christos exc = unpack (except); 972 1.7 christos } 973 1.1 christos 974 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 975 1.1 christos return vlscm_scm_from_value (value); 976 1.1 christos } 977 1.1 christos 978 1.1 christos /* (frame-select <gdb:frame>) -> unspecified 979 1.1 christos Select this frame. */ 980 1.1 christos 981 1.1 christos static SCM 982 1.1 christos gdbscm_frame_select (SCM self) 983 1.8 christos { 984 1.1 christos frame_smob *f_smob; 985 1.1 christos bool found = false; 986 1.1 christos 987 1.7 christos f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 988 1.7 christos 989 1.1 christos gdbscm_gdb_exception exc {}; 990 1.8 christos try 991 1.1 christos { 992 1.8 christos frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob); 993 1.8 christos if (frame != NULL) 994 1.8 christos { 995 1.8 christos found = true; 996 1.1 christos select_frame (frame); 997 1.7 christos } 998 1.3 christos } 999 1.7 christos catch (const gdb_exception &except) 1000 1.3 christos { 1001 1.1 christos exc = unpack (except); 1002 1.7 christos } 1003 1.8 christos 1004 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 1005 1.1 christos if (!found) 1006 1.1 christos { 1007 1.1 christos gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, 1008 1.1 christos _("<gdb:frame>")); 1009 1.1 christos } 1010 1.1 christos 1011 1.1 christos return SCM_UNSPECIFIED; 1012 1.1 christos } 1013 1.1 christos 1014 1.1 christos /* (newest-frame) -> <gdb:frame> 1015 1.1 christos Returns the newest frame. */ 1016 1.1 christos 1017 1.1 christos static SCM 1018 1.1 christos gdbscm_newest_frame (void) 1019 1.1 christos { 1020 1.7 christos struct frame_info *frame = NULL; 1021 1.7 christos 1022 1.1 christos gdbscm_gdb_exception exc {}; 1023 1.8 christos try 1024 1.1 christos { 1025 1.7 christos frame = get_current_frame ().get (); 1026 1.3 christos } 1027 1.7 christos catch (const gdb_exception &except) 1028 1.3 christos { 1029 1.1 christos exc = unpack (except); 1030 1.7 christos } 1031 1.1 christos 1032 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 1033 1.1 christos return frscm_scm_from_frame_unsafe (frame, current_inferior ()); 1034 1.1 christos } 1035 1.1 christos 1036 1.1 christos /* (selected-frame) -> <gdb:frame> 1037 1.1 christos Returns the selected frame. */ 1038 1.1 christos 1039 1.1 christos static SCM 1040 1.1 christos gdbscm_selected_frame (void) 1041 1.1 christos { 1042 1.7 christos struct frame_info *frame = NULL; 1043 1.7 christos 1044 1.1 christos gdbscm_gdb_exception exc {}; 1045 1.8 christos try 1046 1.1 christos { 1047 1.7 christos frame = get_selected_frame (_("No frame is currently selected")).get (); 1048 1.3 christos } 1049 1.7 christos catch (const gdb_exception &except) 1050 1.3 christos { 1051 1.1 christos exc = unpack (except); 1052 1.7 christos } 1053 1.1 christos 1054 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 1055 1.1 christos return frscm_scm_from_frame_unsafe (frame, current_inferior ()); 1056 1.1 christos } 1057 1.1 christos 1058 1.1 christos /* (unwind-stop-reason-string integer) -> string 1059 1.1 christos Return a string explaining the unwind stop reason. */ 1060 1.1 christos 1061 1.1 christos static SCM 1062 1.1 christos gdbscm_unwind_stop_reason_string (SCM reason_scm) 1063 1.1 christos { 1064 1.1 christos int reason; 1065 1.1 christos const char *str; 1066 1.1 christos 1067 1.1 christos gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "i", 1068 1.1 christos reason_scm, &reason); 1069 1.1 christos 1070 1.1 christos if (reason < UNWIND_FIRST || reason > UNWIND_LAST) 1071 1.4 christos scm_out_of_range (FUNC_NAME, reason_scm); 1072 1.1 christos 1073 1.1 christos str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason); 1074 1.1 christos return gdbscm_scm_from_c_string (str); 1075 1.1 christos } 1076 1.1 christos 1077 1.1 christos /* Initialize the Scheme frame support. */ 1079 1.1 christos 1080 1.1 christos static const scheme_integer_constant frame_integer_constants[] = 1081 1.1 christos { 1082 1.1 christos #define ENTRY(X) { #X, X } 1083 1.1 christos 1084 1.1 christos ENTRY (NORMAL_FRAME), 1085 1.1 christos ENTRY (DUMMY_FRAME), 1086 1.1 christos ENTRY (INLINE_FRAME), 1087 1.1 christos ENTRY (TAILCALL_FRAME), 1088 1.1 christos ENTRY (SIGTRAMP_FRAME), 1089 1.1 christos ENTRY (ARCH_FRAME), 1090 1.1 christos ENTRY (SENTINEL_FRAME), 1091 1.1 christos 1092 1.1 christos #undef ENTRY 1093 1.1 christos 1094 1.1 christos #define SET(name, description) \ 1095 1.1 christos { "FRAME_" #name, name }, 1096 1.1 christos #include "unwind_stop_reasons.def" 1097 1.1 christos #undef SET 1098 1.1 christos 1099 1.1 christos END_INTEGER_CONSTANTS 1100 1.1 christos }; 1101 1.4 christos 1102 1.1 christos static const scheme_function frame_functions[] = 1103 1.1 christos { 1104 1.1 christos { "frame?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_p), 1105 1.4 christos "\ 1106 1.1 christos Return #t if the object is a <gdb:frame> object." }, 1107 1.1 christos 1108 1.1 christos { "frame-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_valid_p), 1109 1.1 christos "\ 1110 1.4 christos Return #t if the object is a valid <gdb:frame> object.\n\ 1111 1.1 christos Frames become invalid when the inferior returns to its caller." }, 1112 1.1 christos 1113 1.1 christos { "frame-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_name), 1114 1.1 christos "\ 1115 1.4 christos Return the name of the function corresponding to this frame,\n\ 1116 1.1 christos or #f if there is no function." }, 1117 1.1 christos 1118 1.1 christos { "frame-arch", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_arch), 1119 1.4 christos "\ 1120 1.1 christos Return the frame's architecture as a <gdb:arch> object." }, 1121 1.1 christos 1122 1.1 christos { "frame-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_type), 1123 1.4 christos "\ 1124 1.4 christos Return the frame type, namely one of the gdb:*_FRAME constants." }, 1125 1.1 christos 1126 1.1 christos { "frame-unwind-stop-reason", 1, 0, 0, 1127 1.1 christos as_a_scm_t_subr (gdbscm_frame_unwind_stop_reason), 1128 1.1 christos "\ 1129 1.4 christos Return one of the gdb:FRAME_UNWIND_* constants explaining why\n\ 1130 1.1 christos it's not possible to find frames older than this." }, 1131 1.1 christos 1132 1.1 christos { "frame-pc", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_pc), 1133 1.4 christos "\ 1134 1.1 christos Return the frame's resume address." }, 1135 1.1 christos 1136 1.1 christos { "frame-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_block), 1137 1.4 christos "\ 1138 1.1 christos Return the frame's code block, or #f if one cannot be found." }, 1139 1.1 christos 1140 1.1 christos { "frame-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_function), 1141 1.1 christos "\ 1142 1.4 christos Return the <gdb:symbol> for the function corresponding to this frame,\n\ 1143 1.1 christos or #f if there isn't one." }, 1144 1.1 christos 1145 1.1 christos { "frame-older", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_older), 1146 1.1 christos "\ 1147 1.4 christos Return the frame immediately older (outer) to this frame,\n\ 1148 1.1 christos or #f if there isn't one." }, 1149 1.1 christos 1150 1.1 christos { "frame-newer", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_newer), 1151 1.1 christos "\ 1152 1.4 christos Return the frame immediately newer (inner) to this frame,\n\ 1153 1.1 christos or #f if there isn't one." }, 1154 1.1 christos 1155 1.1 christos { "frame-sal", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_sal), 1156 1.4 christos "\ 1157 1.1 christos Return the frame's symtab-and-line <gdb:sal> object." }, 1158 1.1 christos 1159 1.1 christos { "frame-read-var", 2, 0, 1, as_a_scm_t_subr (gdbscm_frame_read_var), 1160 1.1 christos "\ 1161 1.8 christos Return the value of the symbol in the frame.\n\ 1162 1.1 christos \n\ 1163 1.4 christos Arguments: <gdb:frame> <gdb:symbol>\n\ 1164 1.4 christos Or: <gdb:frame> string [#:block <gdb:block>]" }, 1165 1.3 christos 1166 1.3 christos { "frame-read-register", 2, 0, 0, 1167 1.3 christos as_a_scm_t_subr (gdbscm_frame_read_register), 1168 1.3 christos "\ 1169 1.3 christos Return the value of the register in the frame.\n\ 1170 1.4 christos \n\ 1171 1.1 christos Arguments: <gdb:frame> string" }, 1172 1.1 christos 1173 1.1 christos { "frame-select", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_select), 1174 1.4 christos "\ 1175 1.1 christos Select this frame." }, 1176 1.1 christos 1177 1.1 christos { "newest-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_newest_frame), 1178 1.4 christos "\ 1179 1.1 christos Return the newest frame." }, 1180 1.1 christos 1181 1.1 christos { "selected-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_selected_frame), 1182 1.4 christos "\ 1183 1.4 christos Return the selected frame." }, 1184 1.1 christos 1185 1.1 christos { "unwind-stop-reason-string", 1, 0, 0, 1186 1.1 christos as_a_scm_t_subr (gdbscm_unwind_stop_reason_string), 1187 1.1 christos "\ 1188 1.1 christos Return a string explaining the unwind stop reason.\n\ 1189 1.1 christos \n\ 1190 1.1 christos Arguments: integer (the result of frame-unwind-stop-reason)" }, 1191 1.1 christos 1192 1.1 christos END_FUNCTIONS 1193 1.1 christos }; 1194 1.1 christos 1195 1.1 christos void 1196 1.1 christos gdbscm_initialize_frames (void) 1197 1.1 christos { 1198 1.1 christos frame_smob_tag 1199 1.1 christos = gdbscm_make_smob_type (frame_smob_name, sizeof (frame_smob)); 1200 1.1 christos scm_set_smob_free (frame_smob_tag, frscm_free_frame_smob); 1201 1.1 christos scm_set_smob_print (frame_smob_tag, frscm_print_frame_smob); 1202 1.1 christos 1203 1.1 christos gdbscm_define_integer_constants (frame_integer_constants, 1); 1204 1.1 christos gdbscm_define_functions (frame_functions, 1); 1205 1206 block_keyword = scm_from_latin1_keyword ("block"); 1207 } 1208