1 1.1 christos /* Python interface to inferiors. 2 1.1 christos 3 1.11 christos Copyright (C) 2009-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.10 christos #include "auto-load.h" 21 1.1 christos #include "gdbcore.h" 22 1.1 christos #include "gdbthread.h" 23 1.1 christos #include "inferior.h" 24 1.1 christos #include "objfiles.h" 25 1.8 christos #include "observable.h" 26 1.1 christos #include "python-internal.h" 27 1.1 christos #include "arch-utils.h" 28 1.1 christos #include "language.h" 29 1.9 christos #include "gdbsupport/gdb_signals.h" 30 1.1 christos #include "py-event.h" 31 1.1 christos #include "py-stopevent.h" 32 1.11 christos #include "progspace-and-thread.h" 33 1.10 christos #include <unordered_map> 34 1.1 christos 35 1.10 christos using thread_map_t 36 1.10 christos = std::unordered_map<thread_info *, gdbpy_ref<thread_object>>; 37 1.1 christos 38 1.8 christos struct inferior_object 39 1.1 christos { 40 1.1 christos PyObject_HEAD 41 1.1 christos 42 1.1 christos /* The inferior we represent. */ 43 1.1 christos struct inferior *inferior; 44 1.1 christos 45 1.10 christos /* thread_object instances under this inferior. This owns a 46 1.1 christos reference to each object it contains. */ 47 1.10 christos thread_map_t *threads; 48 1.11 christos 49 1.11 christos /* Dictionary holding user-added attributes. 50 1.11 christos This is the __dict__ attribute of the object. */ 51 1.11 christos PyObject *dict; 52 1.8 christos }; 53 1.1 christos 54 1.5 christos extern PyTypeObject inferior_object_type 55 1.1 christos CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object"); 56 1.1 christos 57 1.10 christos /* Deleter to clean up when an inferior is removed. */ 58 1.10 christos struct infpy_deleter 59 1.10 christos { 60 1.10 christos void operator() (inferior_object *obj) 61 1.10 christos { 62 1.10 christos if (!gdb_python_initialized) 63 1.10 christos return; 64 1.1 christos 65 1.10 christos gdbpy_enter enter_py; 66 1.10 christos gdbpy_ref<inferior_object> inf_obj (obj); 67 1.10 christos 68 1.10 christos inf_obj->inferior = NULL; 69 1.1 christos 70 1.10 christos delete inf_obj->threads; 71 1.10 christos } 72 1.10 christos }; 73 1.1 christos 74 1.10 christos static const registry<inferior>::key<inferior_object, infpy_deleter> 75 1.10 christos infpy_inf_data_key; 76 1.1 christos 77 1.1 christos /* Require that INFERIOR be a valid inferior ID. */ 78 1.1 christos #define INFPY_REQUIRE_VALID(Inferior) \ 79 1.1 christos do { \ 80 1.1 christos if (!Inferior->inferior) \ 81 1.1 christos { \ 82 1.1 christos PyErr_SetString (PyExc_RuntimeError, \ 83 1.1 christos _("Inferior no longer exists.")); \ 84 1.1 christos return NULL; \ 85 1.1 christos } \ 86 1.1 christos } while (0) 87 1.1 christos 88 1.1 christos static void 89 1.10 christos python_on_normal_stop (struct bpstat *bs, int print_frame) 90 1.1 christos { 91 1.1 christos enum gdb_signal stop_signal; 92 1.1 christos 93 1.1 christos if (!gdb_python_initialized) 94 1.1 christos return; 95 1.1 christos 96 1.8 christos if (inferior_ptid == null_ptid) 97 1.8 christos return; 98 1.1 christos 99 1.10 christos stop_signal = inferior_thread ()->stop_signal (); 100 1.1 christos 101 1.10 christos gdbpy_enter enter_py; 102 1.1 christos 103 1.1 christos if (emit_stop_event (bs, stop_signal) < 0) 104 1.1 christos gdbpy_print_stack (); 105 1.1 christos } 106 1.1 christos 107 1.1 christos static void 108 1.1 christos python_on_resume (ptid_t ptid) 109 1.1 christos { 110 1.1 christos if (!gdb_python_initialized) 111 1.1 christos return; 112 1.1 christos 113 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ()); 114 1.1 christos 115 1.1 christos if (emit_continue_event (ptid) < 0) 116 1.1 christos gdbpy_print_stack (); 117 1.1 christos } 118 1.1 christos 119 1.3 christos /* Callback, registered as an observer, that notifies Python listeners 120 1.3 christos when an inferior function call is about to be made. */ 121 1.3 christos 122 1.3 christos static void 123 1.3 christos python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address) 124 1.3 christos { 125 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ()); 126 1.3 christos 127 1.3 christos if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0) 128 1.3 christos gdbpy_print_stack (); 129 1.3 christos } 130 1.3 christos 131 1.3 christos /* Callback, registered as an observer, that notifies Python listeners 132 1.3 christos when an inferior function call has completed. */ 133 1.3 christos 134 1.3 christos static void 135 1.3 christos python_on_inferior_call_post (ptid_t thread, CORE_ADDR address) 136 1.3 christos { 137 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ()); 138 1.3 christos 139 1.3 christos if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0) 140 1.3 christos gdbpy_print_stack (); 141 1.3 christos } 142 1.3 christos 143 1.3 christos /* Callback, registered as an observer, that notifies Python listeners 144 1.3 christos when a part of memory has been modified by user action (eg via a 145 1.3 christos 'set' command). */ 146 1.3 christos 147 1.3 christos static void 148 1.3 christos python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data) 149 1.3 christos { 150 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ()); 151 1.3 christos 152 1.3 christos if (emit_memory_changed_event (addr, len) < 0) 153 1.3 christos gdbpy_print_stack (); 154 1.3 christos } 155 1.3 christos 156 1.3 christos /* Callback, registered as an observer, that notifies Python listeners 157 1.3 christos when a register has been modified by user action (eg via a 'set' 158 1.3 christos command). */ 159 1.3 christos 160 1.3 christos static void 161 1.11 christos python_on_register_change (const frame_info_ptr &frame, int regnum) 162 1.3 christos { 163 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ()); 164 1.3 christos 165 1.3 christos if (emit_register_changed_event (frame, regnum) < 0) 166 1.3 christos gdbpy_print_stack (); 167 1.3 christos } 168 1.3 christos 169 1.1 christos static void 170 1.1 christos python_inferior_exit (struct inferior *inf) 171 1.1 christos { 172 1.1 christos const LONGEST *exit_code = NULL; 173 1.1 christos 174 1.1 christos if (!gdb_python_initialized) 175 1.1 christos return; 176 1.1 christos 177 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ()); 178 1.1 christos 179 1.1 christos if (inf->has_exit_code) 180 1.1 christos exit_code = &inf->exit_code; 181 1.1 christos 182 1.1 christos if (emit_exited_event (exit_code, inf) < 0) 183 1.1 christos gdbpy_print_stack (); 184 1.1 christos } 185 1.1 christos 186 1.1 christos /* Callback used to notify Python listeners about new objfiles loaded in the 187 1.3 christos inferior. OBJFILE may be NULL which means that the objfile list has been 188 1.3 christos cleared (emptied). */ 189 1.1 christos 190 1.1 christos static void 191 1.1 christos python_new_objfile (struct objfile *objfile) 192 1.1 christos { 193 1.1 christos if (!gdb_python_initialized) 194 1.1 christos return; 195 1.1 christos 196 1.11 christos gdbpy_enter enter_py (objfile->arch ()); 197 1.11 christos 198 1.11 christos if (emit_new_objfile_event (objfile) < 0) 199 1.11 christos gdbpy_print_stack (); 200 1.11 christos } 201 1.1 christos 202 1.11 christos static void 203 1.11 christos python_all_objfiles_removed (program_space *pspace) 204 1.11 christos { 205 1.11 christos if (!gdb_python_initialized) 206 1.11 christos return; 207 1.11 christos 208 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ()); 209 1.11 christos 210 1.11 christos if (emit_clear_objfiles_event (pspace) < 0) 211 1.11 christos gdbpy_print_stack (); 212 1.1 christos } 213 1.1 christos 214 1.10 christos /* Emit a Python event when an objfile is about to be removed. */ 215 1.10 christos 216 1.10 christos static void 217 1.10 christos python_free_objfile (struct objfile *objfile) 218 1.10 christos { 219 1.10 christos if (!gdb_python_initialized) 220 1.10 christos return; 221 1.10 christos 222 1.10 christos gdbpy_enter enter_py (objfile->arch ()); 223 1.10 christos 224 1.10 christos if (emit_free_objfile_event (objfile) < 0) 225 1.10 christos gdbpy_print_stack (); 226 1.10 christos } 227 1.10 christos 228 1.1 christos /* Return a reference to the Python object of type Inferior 229 1.1 christos representing INFERIOR. If the object has already been created, 230 1.1 christos return it and increment the reference count, otherwise, create it. 231 1.1 christos Return NULL on failure. */ 232 1.8 christos 233 1.8 christos gdbpy_ref<inferior_object> 234 1.1 christos inferior_to_inferior_object (struct inferior *inferior) 235 1.1 christos { 236 1.1 christos inferior_object *inf_obj; 237 1.1 christos 238 1.10 christos inf_obj = infpy_inf_data_key.get (inferior); 239 1.1 christos if (!inf_obj) 240 1.1 christos { 241 1.1 christos inf_obj = PyObject_New (inferior_object, &inferior_object_type); 242 1.1 christos if (!inf_obj) 243 1.8 christos return NULL; 244 1.1 christos 245 1.1 christos inf_obj->inferior = inferior; 246 1.10 christos inf_obj->threads = new thread_map_t (); 247 1.11 christos inf_obj->dict = PyDict_New (); 248 1.11 christos if (inf_obj->dict == nullptr) 249 1.11 christos return nullptr; 250 1.1 christos 251 1.7 christos /* PyObject_New initializes the new object with a refcount of 1. This 252 1.7 christos counts for the reference we are keeping in the inferior data. */ 253 1.10 christos infpy_inf_data_key.set (inferior, inf_obj); 254 1.1 christos } 255 1.7 christos 256 1.7 christos /* We are returning a new reference. */ 257 1.8 christos gdb_assert (inf_obj != nullptr); 258 1.8 christos return gdbpy_ref<inferior_object>::new_reference (inf_obj); 259 1.8 christos } 260 1.1 christos 261 1.8 christos /* Called when a new inferior is created. Notifies any Python event 262 1.8 christos listeners. */ 263 1.8 christos static void 264 1.8 christos python_new_inferior (struct inferior *inf) 265 1.8 christos { 266 1.8 christos if (!gdb_python_initialized) 267 1.8 christos return; 268 1.1 christos 269 1.10 christos gdbpy_enter enter_py; 270 1.1 christos 271 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.new_inferior)) 272 1.8 christos return; 273 1.1 christos 274 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf); 275 1.8 christos if (inf_obj == NULL) 276 1.8 christos { 277 1.8 christos gdbpy_print_stack (); 278 1.8 christos return; 279 1.8 christos } 280 1.1 christos 281 1.8 christos gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type); 282 1.8 christos if (event == NULL 283 1.8 christos || evpy_add_attribute (event.get (), "inferior", 284 1.8 christos (PyObject *) inf_obj.get ()) < 0 285 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0) 286 1.8 christos gdbpy_print_stack (); 287 1.1 christos } 288 1.1 christos 289 1.8 christos /* Called when an inferior is removed. Notifies any Python event 290 1.8 christos listeners. */ 291 1.8 christos static void 292 1.8 christos python_inferior_deleted (struct inferior *inf) 293 1.1 christos { 294 1.8 christos if (!gdb_python_initialized) 295 1.8 christos return; 296 1.1 christos 297 1.10 christos gdbpy_enter enter_py; 298 1.8 christos 299 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted)) 300 1.8 christos return; 301 1.8 christos 302 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf); 303 1.8 christos if (inf_obj == NULL) 304 1.8 christos { 305 1.8 christos gdbpy_print_stack (); 306 1.8 christos return; 307 1.8 christos } 308 1.8 christos 309 1.8 christos gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type); 310 1.8 christos if (event == NULL 311 1.8 christos || evpy_add_attribute (event.get (), "inferior", 312 1.8 christos (PyObject *) inf_obj.get ()) < 0 313 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0) 314 1.8 christos gdbpy_print_stack (); 315 1.8 christos } 316 1.1 christos 317 1.8 christos gdbpy_ref<> 318 1.8 christos thread_to_thread_object (thread_info *thr) 319 1.8 christos { 320 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf); 321 1.7 christos if (inf_obj == NULL) 322 1.1 christos return NULL; 323 1.1 christos 324 1.10 christos auto thread_it = inf_obj->threads->find (thr); 325 1.10 christos if (thread_it != inf_obj->threads->end ()) 326 1.10 christos return gdbpy_ref<>::new_reference 327 1.10 christos ((PyObject *) (thread_it->second.get ())); 328 1.1 christos 329 1.8 christos PyErr_SetString (PyExc_SystemError, 330 1.8 christos _("could not find gdb thread object")); 331 1.1 christos return NULL; 332 1.1 christos } 333 1.1 christos 334 1.1 christos static void 335 1.1 christos add_thread_object (struct thread_info *tp) 336 1.1 christos { 337 1.1 christos inferior_object *inf_obj; 338 1.1 christos 339 1.1 christos if (!gdb_python_initialized) 340 1.1 christos return; 341 1.1 christos 342 1.10 christos gdbpy_enter enter_py; 343 1.1 christos 344 1.9 christos gdbpy_ref<thread_object> thread_obj = create_thread_object (tp); 345 1.9 christos if (thread_obj == NULL) 346 1.1 christos { 347 1.1 christos gdbpy_print_stack (); 348 1.1 christos return; 349 1.1 christos } 350 1.1 christos 351 1.1 christos inf_obj = (inferior_object *) thread_obj->inf_obj; 352 1.1 christos 353 1.10 christos auto ins_result = inf_obj->threads->emplace 354 1.10 christos (thread_map_t::value_type (tp, std::move (thread_obj))); 355 1.1 christos 356 1.10 christos if (!ins_result.second) 357 1.10 christos return; 358 1.8 christos 359 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.new_thread)) 360 1.8 christos return; 361 1.8 christos 362 1.10 christos gdbpy_ref<> event = create_thread_event_object 363 1.10 christos (&new_thread_event_object_type, 364 1.10 christos (PyObject *) ins_result.first->second.get ()); 365 1.10 christos 366 1.8 christos if (event == NULL 367 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0) 368 1.8 christos gdbpy_print_stack (); 369 1.1 christos } 370 1.1 christos 371 1.1 christos static void 372 1.11 christos delete_thread_object (thread_info *tp, 373 1.11 christos std::optional<ULONGEST> /* exit_code */, 374 1.11 christos bool /* silent */) 375 1.1 christos { 376 1.1 christos if (!gdb_python_initialized) 377 1.1 christos return; 378 1.1 christos 379 1.10 christos gdbpy_enter enter_py; 380 1.1 christos 381 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf); 382 1.7 christos if (inf_obj == NULL) 383 1.7 christos return; 384 1.1 christos 385 1.11 christos if (emit_thread_exit_event (tp) < 0) 386 1.11 christos gdbpy_print_stack (); 387 1.11 christos 388 1.10 christos auto it = inf_obj->threads->find (tp); 389 1.10 christos if (it != inf_obj->threads->end ()) 390 1.10 christos { 391 1.10 christos /* Some python code can still hold a reference to the thread_object 392 1.10 christos instance. Make sure to remove the link to the associated 393 1.10 christos thread_info object as it will be freed soon. This makes the python 394 1.10 christos object invalid (i.e. gdb.InfThread.is_valid returns False). */ 395 1.10 christos it->second->thread = nullptr; 396 1.10 christos inf_obj->threads->erase (it); 397 1.10 christos } 398 1.1 christos } 399 1.1 christos 400 1.1 christos static PyObject * 401 1.1 christos infpy_threads (PyObject *self, PyObject *args) 402 1.1 christos { 403 1.10 christos int i = 0; 404 1.1 christos inferior_object *inf_obj = (inferior_object *) self; 405 1.1 christos PyObject *tuple; 406 1.1 christos 407 1.1 christos INFPY_REQUIRE_VALID (inf_obj); 408 1.1 christos 409 1.9 christos try 410 1.5 christos { 411 1.5 christos update_thread_list (); 412 1.5 christos } 413 1.9 christos catch (const gdb_exception &except) 414 1.5 christos { 415 1.12 christos return gdbpy_handle_gdb_exception (nullptr, except); 416 1.5 christos } 417 1.1 christos 418 1.10 christos tuple = PyTuple_New (inf_obj->threads->size ()); 419 1.1 christos if (!tuple) 420 1.1 christos return NULL; 421 1.1 christos 422 1.10 christos for (const thread_map_t::value_type &entry : *inf_obj->threads) 423 1.1 christos { 424 1.10 christos PyObject *thr = (PyObject *) entry.second.get (); 425 1.9 christos Py_INCREF (thr); 426 1.9 christos PyTuple_SET_ITEM (tuple, i, thr); 427 1.10 christos i = i + 1; 428 1.1 christos } 429 1.1 christos 430 1.1 christos return tuple; 431 1.1 christos } 432 1.1 christos 433 1.1 christos static PyObject * 434 1.1 christos infpy_get_num (PyObject *self, void *closure) 435 1.1 christos { 436 1.1 christos inferior_object *inf = (inferior_object *) self; 437 1.1 christos 438 1.1 christos INFPY_REQUIRE_VALID (inf); 439 1.1 christos 440 1.10 christos return gdb_py_object_from_longest (inf->inferior->num).release (); 441 1.10 christos } 442 1.10 christos 443 1.10 christos /* Return the gdb.TargetConnection object for this inferior, or None if a 444 1.10 christos connection does not exist. */ 445 1.10 christos 446 1.10 christos static PyObject * 447 1.10 christos infpy_get_connection (PyObject *self, void *closure) 448 1.10 christos { 449 1.10 christos inferior_object *inf = (inferior_object *) self; 450 1.10 christos 451 1.10 christos INFPY_REQUIRE_VALID (inf); 452 1.10 christos 453 1.10 christos process_stratum_target *target = inf->inferior->process_target (); 454 1.10 christos return target_to_connection_object (target).release (); 455 1.10 christos } 456 1.10 christos 457 1.10 christos /* Return the connection number of the given inferior, or None if a 458 1.10 christos connection does not exist. */ 459 1.10 christos 460 1.10 christos static PyObject * 461 1.10 christos infpy_get_connection_num (PyObject *self, void *closure) 462 1.10 christos { 463 1.10 christos inferior_object *inf = (inferior_object *) self; 464 1.10 christos 465 1.10 christos INFPY_REQUIRE_VALID (inf); 466 1.10 christos 467 1.10 christos process_stratum_target *target = inf->inferior->process_target (); 468 1.10 christos if (target == nullptr) 469 1.10 christos Py_RETURN_NONE; 470 1.10 christos 471 1.10 christos return gdb_py_object_from_longest (target->connection_number).release (); 472 1.1 christos } 473 1.1 christos 474 1.1 christos static PyObject * 475 1.1 christos infpy_get_pid (PyObject *self, void *closure) 476 1.1 christos { 477 1.1 christos inferior_object *inf = (inferior_object *) self; 478 1.1 christos 479 1.1 christos INFPY_REQUIRE_VALID (inf); 480 1.1 christos 481 1.10 christos return gdb_py_object_from_longest (inf->inferior->pid).release (); 482 1.1 christos } 483 1.1 christos 484 1.1 christos static PyObject * 485 1.1 christos infpy_get_was_attached (PyObject *self, void *closure) 486 1.1 christos { 487 1.1 christos inferior_object *inf = (inferior_object *) self; 488 1.1 christos 489 1.1 christos INFPY_REQUIRE_VALID (inf); 490 1.1 christos if (inf->inferior->attach_flag) 491 1.1 christos Py_RETURN_TRUE; 492 1.1 christos Py_RETURN_FALSE; 493 1.1 christos } 494 1.1 christos 495 1.8 christos /* Getter of gdb.Inferior.progspace. */ 496 1.8 christos 497 1.8 christos static PyObject * 498 1.8 christos infpy_get_progspace (PyObject *self, void *closure) 499 1.8 christos { 500 1.8 christos inferior_object *inf = (inferior_object *) self; 501 1.8 christos 502 1.8 christos INFPY_REQUIRE_VALID (inf); 503 1.8 christos 504 1.8 christos program_space *pspace = inf->inferior->pspace; 505 1.8 christos gdb_assert (pspace != nullptr); 506 1.8 christos 507 1.8 christos return pspace_to_pspace_object (pspace).release (); 508 1.8 christos } 509 1.8 christos 510 1.1 christos /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). 511 1.1 christos Returns a tuple of all inferiors. */ 512 1.1 christos PyObject * 513 1.1 christos gdbpy_inferiors (PyObject *unused, PyObject *unused2) 514 1.1 christos { 515 1.7 christos gdbpy_ref<> list (PyList_New (0)); 516 1.7 christos if (list == NULL) 517 1.7 christos return NULL; 518 1.1 christos 519 1.9 christos for (inferior *inf : all_inferiors ()) 520 1.9 christos { 521 1.9 christos gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf); 522 1.9 christos 523 1.9 christos if (inferior == NULL) 524 1.9 christos continue; 525 1.9 christos 526 1.9 christos if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0) 527 1.9 christos return NULL; 528 1.9 christos } 529 1.1 christos 530 1.7 christos return PyList_AsTuple (list.get ()); 531 1.1 christos } 532 1.1 christos 533 1.1 christos /* Membuf and memory manipulation. */ 534 1.1 christos 535 1.1 christos /* Implementation of Inferior.read_memory (address, length). 536 1.1 christos Returns a Python buffer object with LENGTH bytes of the inferior's 537 1.1 christos memory at ADDRESS. Both arguments are integers. Returns NULL on error, 538 1.1 christos with a python exception set. */ 539 1.1 christos static PyObject * 540 1.1 christos infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw) 541 1.1 christos { 542 1.11 christos inferior_object *inf = (inferior_object *) self; 543 1.1 christos CORE_ADDR addr, length; 544 1.8 christos gdb::unique_xmalloc_ptr<gdb_byte> buffer; 545 1.10 christos PyObject *addr_obj, *length_obj; 546 1.7 christos static const char *keywords[] = { "address", "length", NULL }; 547 1.1 christos 548 1.11 christos INFPY_REQUIRE_VALID (inf); 549 1.11 christos 550 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords, 551 1.7 christos &addr_obj, &length_obj)) 552 1.1 christos return NULL; 553 1.1 christos 554 1.1 christos if (get_addr_from_python (addr_obj, &addr) < 0 555 1.1 christos || get_addr_from_python (length_obj, &length) < 0) 556 1.1 christos return NULL; 557 1.1 christos 558 1.11 christos if (length == 0) 559 1.11 christos { 560 1.11 christos PyErr_SetString (PyExc_ValueError, 561 1.11 christos _("Argument 'count' should be greater than zero")); 562 1.11 christos return NULL; 563 1.11 christos } 564 1.11 christos 565 1.11 christos void *p = malloc (length); 566 1.11 christos if (p == nullptr) 567 1.11 christos return PyErr_NoMemory (); 568 1.11 christos buffer.reset ((gdb_byte *) p); 569 1.11 christos 570 1.9 christos try 571 1.1 christos { 572 1.11 christos /* Use this scoped-restore because we want to be able to read 573 1.11 christos memory from an unwinder. */ 574 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior 575 1.11 christos (inf->inferior); 576 1.1 christos 577 1.8 christos read_memory (addr, buffer.get (), length); 578 1.1 christos } 579 1.9 christos catch (const gdb_exception &except) 580 1.1 christos { 581 1.12 christos return gdbpy_handle_gdb_exception (nullptr, except); 582 1.1 christos } 583 1.1 christos 584 1.1 christos 585 1.10 christos return gdbpy_buffer_to_membuf (std::move (buffer), addr, length); 586 1.1 christos } 587 1.1 christos 588 1.1 christos /* Implementation of Inferior.write_memory (address, buffer [, length]). 589 1.1 christos Writes the contents of BUFFER (a Python object supporting the read 590 1.1 christos buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH 591 1.1 christos bytes from BUFFER, or its entire contents if the argument is not 592 1.1 christos provided. The function returns nothing. Returns NULL on error, with 593 1.1 christos a python exception set. */ 594 1.1 christos static PyObject * 595 1.1 christos infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw) 596 1.1 christos { 597 1.11 christos inferior_object *inf = (inferior_object *) self; 598 1.1 christos Py_ssize_t buf_len; 599 1.6 christos const gdb_byte *buffer; 600 1.1 christos CORE_ADDR addr, length; 601 1.1 christos PyObject *addr_obj, *length_obj = NULL; 602 1.7 christos static const char *keywords[] = { "address", "buffer", "length", NULL }; 603 1.1 christos Py_buffer pybuf; 604 1.1 christos 605 1.11 christos INFPY_REQUIRE_VALID (inf); 606 1.11 christos 607 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords, 608 1.7 christos &addr_obj, &pybuf, &length_obj)) 609 1.1 christos return NULL; 610 1.1 christos 611 1.9 christos Py_buffer_up buffer_up (&pybuf); 612 1.6 christos buffer = (const gdb_byte *) pybuf.buf; 613 1.1 christos buf_len = pybuf.len; 614 1.1 christos 615 1.1 christos if (get_addr_from_python (addr_obj, &addr) < 0) 616 1.9 christos return nullptr; 617 1.1 christos 618 1.1 christos if (!length_obj) 619 1.1 christos length = buf_len; 620 1.1 christos else if (get_addr_from_python (length_obj, &length) < 0) 621 1.9 christos return nullptr; 622 1.1 christos 623 1.9 christos try 624 1.1 christos { 625 1.11 christos /* It's probably not too important to avoid invalidating the 626 1.11 christos frame cache when writing memory, but this scoped-restore is 627 1.11 christos still used here, just to keep the code similar to other code 628 1.11 christos in this file. */ 629 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior 630 1.11 christos (inf->inferior); 631 1.11 christos 632 1.6 christos write_memory_with_notification (addr, buffer, length); 633 1.1 christos } 634 1.12 christos catch (const gdb_exception &ex) 635 1.5 christos { 636 1.12 christos return gdbpy_handle_gdb_exception (nullptr, ex); 637 1.5 christos } 638 1.5 christos 639 1.1 christos Py_RETURN_NONE; 640 1.1 christos } 641 1.1 christos 642 1.1 christos /* Implementation of 643 1.11 christos Inferior.search_memory (address, length, pattern). ADDRESS is the 644 1.1 christos address to start the search. LENGTH specifies the scope of the 645 1.1 christos search from ADDRESS. PATTERN is the pattern to search for (and 646 1.1 christos must be a Python object supporting the buffer protocol). 647 1.1 christos Returns a Python Long object holding the address where the pattern 648 1.1 christos was located, or if the pattern was not found, returns None. Returns NULL 649 1.1 christos on error, with a python exception set. */ 650 1.1 christos static PyObject * 651 1.1 christos infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) 652 1.1 christos { 653 1.11 christos inferior_object *inf = (inferior_object *) self; 654 1.1 christos CORE_ADDR start_addr, length; 655 1.7 christos static const char *keywords[] = { "address", "length", "pattern", NULL }; 656 1.1 christos PyObject *start_addr_obj, *length_obj; 657 1.1 christos Py_ssize_t pattern_size; 658 1.6 christos const gdb_byte *buffer; 659 1.1 christos CORE_ADDR found_addr; 660 1.1 christos int found = 0; 661 1.1 christos Py_buffer pybuf; 662 1.1 christos 663 1.11 christos INFPY_REQUIRE_VALID (inf); 664 1.11 christos 665 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords, 666 1.7 christos &start_addr_obj, &length_obj, 667 1.7 christos &pybuf)) 668 1.1 christos return NULL; 669 1.1 christos 670 1.9 christos Py_buffer_up buffer_up (&pybuf); 671 1.6 christos buffer = (const gdb_byte *) pybuf.buf; 672 1.1 christos pattern_size = pybuf.len; 673 1.1 christos 674 1.1 christos if (get_addr_from_python (start_addr_obj, &start_addr) < 0) 675 1.9 christos return nullptr; 676 1.1 christos 677 1.1 christos if (get_addr_from_python (length_obj, &length) < 0) 678 1.9 christos return nullptr; 679 1.1 christos 680 1.1 christos if (!length) 681 1.1 christos { 682 1.1 christos PyErr_SetString (PyExc_ValueError, 683 1.1 christos _("Search range is empty.")); 684 1.9 christos return nullptr; 685 1.1 christos } 686 1.1 christos /* Watch for overflows. */ 687 1.1 christos else if (length > CORE_ADDR_MAX 688 1.1 christos || (start_addr + length - 1) < start_addr) 689 1.1 christos { 690 1.1 christos PyErr_SetString (PyExc_ValueError, 691 1.1 christos _("The search range is too large.")); 692 1.9 christos return nullptr; 693 1.1 christos } 694 1.1 christos 695 1.9 christos try 696 1.1 christos { 697 1.11 christos /* It's probably not too important to avoid invalidating the 698 1.11 christos frame cache when searching memory, but this scoped-restore is 699 1.11 christos still used here, just to keep the code similar to other code 700 1.11 christos in this file. */ 701 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior 702 1.11 christos (inf->inferior); 703 1.11 christos 704 1.1 christos found = target_search_memory (start_addr, length, 705 1.1 christos buffer, pattern_size, 706 1.1 christos &found_addr); 707 1.1 christos } 708 1.12 christos catch (const gdb_exception &ex) 709 1.5 christos { 710 1.12 christos return gdbpy_handle_gdb_exception (nullptr, ex); 711 1.5 christos } 712 1.5 christos 713 1.1 christos if (found) 714 1.9 christos return gdb_py_object_from_ulongest (found_addr).release (); 715 1.1 christos else 716 1.1 christos Py_RETURN_NONE; 717 1.1 christos } 718 1.1 christos 719 1.1 christos /* Implementation of gdb.Inferior.is_valid (self) -> Boolean. 720 1.1 christos Returns True if this inferior object still exists in GDB. */ 721 1.1 christos 722 1.1 christos static PyObject * 723 1.1 christos infpy_is_valid (PyObject *self, PyObject *args) 724 1.1 christos { 725 1.1 christos inferior_object *inf = (inferior_object *) self; 726 1.1 christos 727 1.1 christos if (! inf->inferior) 728 1.1 christos Py_RETURN_FALSE; 729 1.1 christos 730 1.1 christos Py_RETURN_TRUE; 731 1.1 christos } 732 1.1 christos 733 1.9 christos /* Implementation of gdb.Inferior.thread_from_handle (self, handle) 734 1.10 christos -> gdb.InferiorThread. */ 735 1.8 christos 736 1.8 christos static PyObject * 737 1.8 christos infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw) 738 1.8 christos { 739 1.8 christos PyObject *handle_obj; 740 1.8 christos inferior_object *inf_obj = (inferior_object *) self; 741 1.9 christos static const char *keywords[] = { "handle", NULL }; 742 1.8 christos 743 1.8 christos INFPY_REQUIRE_VALID (inf_obj); 744 1.8 christos 745 1.8 christos if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj)) 746 1.8 christos return NULL; 747 1.8 christos 748 1.9 christos const gdb_byte *bytes; 749 1.9 christos size_t bytes_len; 750 1.9 christos Py_buffer_up buffer_up; 751 1.9 christos Py_buffer py_buf; 752 1.9 christos 753 1.9 christos if (PyObject_CheckBuffer (handle_obj) 754 1.9 christos && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0) 755 1.9 christos { 756 1.9 christos buffer_up.reset (&py_buf); 757 1.9 christos bytes = (const gdb_byte *) py_buf.buf; 758 1.9 christos bytes_len = py_buf.len; 759 1.9 christos } 760 1.9 christos else if (gdbpy_is_value_object (handle_obj)) 761 1.9 christos { 762 1.9 christos struct value *val = value_object_to_value (handle_obj); 763 1.11 christos bytes = val->contents_all ().data (); 764 1.11 christos bytes_len = val->type ()->length (); 765 1.9 christos } 766 1.9 christos else 767 1.8 christos { 768 1.8 christos PyErr_SetString (PyExc_TypeError, 769 1.9 christos _("Argument 'handle' must be a thread handle object.")); 770 1.8 christos 771 1.8 christos return NULL; 772 1.8 christos } 773 1.8 christos 774 1.9 christos try 775 1.8 christos { 776 1.8 christos struct thread_info *thread_info; 777 1.8 christos 778 1.9 christos thread_info = find_thread_by_handle 779 1.10 christos (gdb::array_view<const gdb_byte> (bytes, bytes_len), 780 1.9 christos inf_obj->inferior); 781 1.8 christos if (thread_info != NULL) 782 1.8 christos return thread_to_thread_object (thread_info).release (); 783 1.8 christos } 784 1.9 christos catch (const gdb_exception &except) 785 1.8 christos { 786 1.12 christos return gdbpy_handle_gdb_exception (nullptr, except); 787 1.8 christos } 788 1.8 christos 789 1.8 christos Py_RETURN_NONE; 790 1.8 christos } 791 1.8 christos 792 1.8 christos /* Implementation of gdb.Inferior.architecture. */ 793 1.8 christos 794 1.8 christos static PyObject * 795 1.8 christos infpy_architecture (PyObject *self, PyObject *args) 796 1.8 christos { 797 1.8 christos inferior_object *inf = (inferior_object *) self; 798 1.8 christos 799 1.8 christos INFPY_REQUIRE_VALID (inf); 800 1.8 christos 801 1.11 christos return gdbarch_to_arch_object (inf->inferior->arch ()); 802 1.8 christos } 803 1.8 christos 804 1.8 christos /* Implement repr() for gdb.Inferior. */ 805 1.8 christos 806 1.8 christos static PyObject * 807 1.8 christos infpy_repr (PyObject *obj) 808 1.8 christos { 809 1.8 christos inferior_object *self = (inferior_object *) obj; 810 1.8 christos inferior *inf = self->inferior; 811 1.8 christos 812 1.8 christos if (inf == nullptr) 813 1.11 christos return gdb_py_invalid_object_repr (obj); 814 1.8 christos 815 1.10 christos return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>", 816 1.10 christos inf->num, inf->pid); 817 1.8 christos } 818 1.8 christos 819 1.11 christos /* Implement clear_env. */ 820 1.11 christos 821 1.11 christos static PyObject * 822 1.11 christos infpy_clear_env (PyObject *obj) 823 1.11 christos { 824 1.11 christos inferior_object *self = (inferior_object *) obj; 825 1.11 christos 826 1.11 christos INFPY_REQUIRE_VALID (self); 827 1.11 christos 828 1.11 christos self->inferior->environment.clear (); 829 1.11 christos Py_RETURN_NONE; 830 1.11 christos } 831 1.11 christos 832 1.11 christos /* Implement set_env. */ 833 1.11 christos 834 1.11 christos static PyObject * 835 1.11 christos infpy_set_env (PyObject *obj, PyObject *args, PyObject *kw) 836 1.11 christos { 837 1.11 christos inferior_object *self = (inferior_object *) obj; 838 1.11 christos INFPY_REQUIRE_VALID (self); 839 1.11 christos 840 1.11 christos const char *name, *val; 841 1.11 christos static const char *keywords[] = { "name", "value", nullptr }; 842 1.11 christos 843 1.11 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "ss", keywords, 844 1.11 christos &name, &val)) 845 1.11 christos return nullptr; 846 1.11 christos 847 1.11 christos self->inferior->environment.set (name, val); 848 1.11 christos Py_RETURN_NONE; 849 1.11 christos } 850 1.11 christos 851 1.11 christos /* Implement unset_env. */ 852 1.11 christos 853 1.11 christos static PyObject * 854 1.11 christos infpy_unset_env (PyObject *obj, PyObject *args, PyObject *kw) 855 1.11 christos { 856 1.11 christos inferior_object *self = (inferior_object *) obj; 857 1.11 christos INFPY_REQUIRE_VALID (self); 858 1.11 christos 859 1.11 christos const char *name; 860 1.11 christos static const char *keywords[] = { "name", nullptr }; 861 1.11 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &name)) 862 1.11 christos return nullptr; 863 1.11 christos 864 1.11 christos self->inferior->environment.unset (name); 865 1.11 christos Py_RETURN_NONE; 866 1.11 christos } 867 1.11 christos 868 1.11 christos /* Getter for "arguments". */ 869 1.11 christos 870 1.11 christos static PyObject * 871 1.11 christos infpy_get_args (PyObject *self, void *closure) 872 1.11 christos { 873 1.11 christos inferior_object *inf = (inferior_object *) self; 874 1.11 christos 875 1.11 christos INFPY_REQUIRE_VALID (inf); 876 1.11 christos 877 1.11 christos const std::string &args = inf->inferior->args (); 878 1.11 christos if (args.empty ()) 879 1.11 christos Py_RETURN_NONE; 880 1.11 christos 881 1.11 christos return host_string_to_python_string (args.c_str ()).release (); 882 1.11 christos } 883 1.11 christos 884 1.11 christos /* Setter for "arguments". */ 885 1.11 christos 886 1.11 christos static int 887 1.11 christos infpy_set_args (PyObject *self, PyObject *value, void *closure) 888 1.11 christos { 889 1.11 christos inferior_object *inf = (inferior_object *) self; 890 1.11 christos 891 1.11 christos if (!inf->inferior) 892 1.11 christos { 893 1.11 christos PyErr_SetString (PyExc_RuntimeError, _("Inferior no longer exists.")); 894 1.11 christos return -1; 895 1.11 christos } 896 1.11 christos 897 1.11 christos if (value == nullptr) 898 1.11 christos { 899 1.11 christos PyErr_SetString (PyExc_TypeError, 900 1.11 christos _("Cannot delete 'arguments' attribute.")); 901 1.11 christos return -1; 902 1.11 christos } 903 1.11 christos 904 1.11 christos if (gdbpy_is_string (value)) 905 1.11 christos { 906 1.11 christos gdb::unique_xmalloc_ptr<char> str = python_string_to_host_string (value); 907 1.11 christos if (str == nullptr) 908 1.11 christos return -1; 909 1.11 christos inf->inferior->set_args (std::string (str.get ())); 910 1.11 christos } 911 1.11 christos else if (PySequence_Check (value)) 912 1.11 christos { 913 1.11 christos std::vector<gdb::unique_xmalloc_ptr<char>> args; 914 1.11 christos Py_ssize_t len = PySequence_Size (value); 915 1.11 christos if (len == -1) 916 1.11 christos return -1; 917 1.11 christos for (Py_ssize_t i = 0; i < len; ++i) 918 1.11 christos { 919 1.11 christos gdbpy_ref<> item (PySequence_ITEM (value, i)); 920 1.11 christos if (item == nullptr) 921 1.11 christos return -1; 922 1.11 christos gdb::unique_xmalloc_ptr<char> str 923 1.11 christos = python_string_to_host_string (item.get ()); 924 1.11 christos if (str == nullptr) 925 1.11 christos return -1; 926 1.11 christos args.push_back (std::move (str)); 927 1.11 christos } 928 1.11 christos std::vector<char *> argvec; 929 1.11 christos for (const auto &arg : args) 930 1.11 christos argvec.push_back (arg.get ()); 931 1.11 christos gdb::array_view<char * const> view (argvec.data (), argvec.size ()); 932 1.11 christos inf->inferior->set_args (view); 933 1.11 christos } 934 1.11 christos else 935 1.11 christos { 936 1.11 christos PyErr_SetString (PyExc_TypeError, 937 1.11 christos _("string or sequence required for 'arguments'")); 938 1.11 christos return -1; 939 1.11 christos } 940 1.11 christos return 0; 941 1.11 christos } 942 1.11 christos 943 1.11 christos /* Getter for "main_name". */ 944 1.11 christos 945 1.11 christos static PyObject * 946 1.11 christos infpy_get_main_name (PyObject *self, void *closure) 947 1.11 christos { 948 1.11 christos inferior_object *inf = (inferior_object *) self; 949 1.11 christos 950 1.11 christos INFPY_REQUIRE_VALID (inf); 951 1.11 christos 952 1.11 christos const char *name = nullptr; 953 1.11 christos try 954 1.11 christos { 955 1.11 christos /* This is unfortunate but the implementation of main_name can 956 1.11 christos reach into memory. It's probably not too important to avoid 957 1.11 christos invalidating the frame cache here, but this scoped-restore is 958 1.11 christos still used, just to keep the code similar to other code in 959 1.11 christos this file. */ 960 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior 961 1.11 christos (inf->inferior); 962 1.11 christos 963 1.11 christos name = main_name (); 964 1.11 christos } 965 1.11 christos catch (const gdb_exception &except) 966 1.11 christos { 967 1.11 christos /* We can just ignore this. */ 968 1.11 christos } 969 1.11 christos 970 1.11 christos if (name == nullptr) 971 1.11 christos Py_RETURN_NONE; 972 1.11 christos 973 1.11 christos return host_string_to_python_string (name).release (); 974 1.11 christos } 975 1.8 christos 976 1.1 christos static void 977 1.1 christos infpy_dealloc (PyObject *obj) 978 1.1 christos { 979 1.1 christos inferior_object *inf_obj = (inferior_object *) obj; 980 1.1 christos 981 1.10 christos /* The inferior itself holds a reference to this Python object, which 982 1.10 christos will keep the reference count of this object above zero until GDB 983 1.10 christos deletes the inferior and py_free_inferior is called. 984 1.10 christos 985 1.10 christos Once py_free_inferior has been called then the link between this 986 1.10 christos Python object and the inferior is set to nullptr, and then the 987 1.10 christos reference count on this Python object is decremented. 988 1.10 christos 989 1.10 christos The result of all this is that the link between this Python object and 990 1.10 christos the inferior should always have been set to nullptr before this 991 1.10 christos function is called. */ 992 1.10 christos gdb_assert (inf_obj->inferior == nullptr); 993 1.1 christos 994 1.11 christos Py_XDECREF (inf_obj->dict); 995 1.11 christos 996 1.9 christos Py_TYPE (obj)->tp_free (obj); 997 1.1 christos } 998 1.1 christos 999 1.1 christos /* Implementation of gdb.selected_inferior() -> gdb.Inferior. 1000 1.1 christos Returns the current inferior object. */ 1001 1.1 christos 1002 1.1 christos PyObject * 1003 1.1 christos gdbpy_selected_inferior (PyObject *self, PyObject *args) 1004 1.1 christos { 1005 1.8 christos return ((PyObject *) 1006 1.8 christos inferior_to_inferior_object (current_inferior ()).release ()); 1007 1.1 christos } 1008 1.1 christos 1009 1.11 christos static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION 1010 1.1 christos gdbpy_initialize_inferior (void) 1011 1.1 christos { 1012 1.12 christos if (gdbpy_type_ready (&inferior_object_type) < 0) 1013 1.1 christos return -1; 1014 1.1 christos 1015 1.10 christos gdb::observers::new_thread.attach (add_thread_object, "py-inferior"); 1016 1.10 christos gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior"); 1017 1.10 christos gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior"); 1018 1.10 christos gdb::observers::target_resumed.attach (python_on_resume, "py-inferior"); 1019 1.10 christos gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre, 1020 1.10 christos "py-inferior"); 1021 1.10 christos gdb::observers::inferior_call_post.attach (python_on_inferior_call_post, 1022 1.10 christos "py-inferior"); 1023 1.10 christos gdb::observers::memory_changed.attach (python_on_memory_change, 1024 1.10 christos "py-inferior"); 1025 1.10 christos gdb::observers::register_changed.attach (python_on_register_change, 1026 1.10 christos "py-inferior"); 1027 1.10 christos gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior"); 1028 1.10 christos /* Need to run after auto-load's new_objfile observer, so that 1029 1.10 christos auto-loaded pretty-printers are available. */ 1030 1.10 christos gdb::observers::new_objfile.attach 1031 1.10 christos (python_new_objfile, "py-inferior", 1032 1.10 christos { &auto_load_new_objfile_observer_token }); 1033 1.11 christos gdb::observers::all_objfiles_removed.attach (python_all_objfiles_removed, 1034 1.11 christos "py-inferior"); 1035 1.10 christos gdb::observers::free_objfile.attach (python_free_objfile, "py-inferior"); 1036 1.10 christos gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior"); 1037 1.10 christos gdb::observers::inferior_removed.attach (python_inferior_deleted, 1038 1.10 christos "py-inferior"); 1039 1.1 christos 1040 1.10 christos return 0; 1041 1.1 christos } 1042 1.1 christos 1043 1.11 christos GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior); 1044 1.11 christos 1045 1.11 christos 1046 1.11 christos 1048 1.1 christos static gdb_PyGetSetDef inferior_object_getset[] = 1049 1.11 christos { 1050 1.11 christos { "__dict__", gdb_py_generic_dict, nullptr, 1051 1.11 christos "The __dict__ for this inferior.", &inferior_object_type }, 1052 1.11 christos { "arguments", infpy_get_args, infpy_set_args, 1053 1.1 christos "Arguments to this program.", nullptr }, 1054 1.10 christos { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL }, 1055 1.10 christos { "connection", infpy_get_connection, NULL, 1056 1.10 christos "The gdb.TargetConnection for this inferior.", NULL }, 1057 1.10 christos { "connection_num", infpy_get_connection_num, NULL, 1058 1.1 christos "ID of inferior's connection, as assigned by GDB.", NULL }, 1059 1.1 christos { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.", 1060 1.1 christos NULL }, 1061 1.1 christos { "was_attached", infpy_get_was_attached, NULL, 1062 1.8 christos "True if the inferior was created using 'attach'.", NULL }, 1063 1.11 christos { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" }, 1064 1.11 christos { "main_name", infpy_get_main_name, nullptr, 1065 1.1 christos "Name of 'main' function, if known.", nullptr }, 1066 1.1 christos { NULL } 1067 1.1 christos }; 1068 1.1 christos 1069 1.1 christos static PyMethodDef inferior_object_methods[] = 1070 1.1 christos { 1071 1.1 christos { "is_valid", infpy_is_valid, METH_NOARGS, 1072 1.1 christos "is_valid () -> Boolean.\n\ 1073 1.1 christos Return true if this inferior is valid, false if not." }, 1074 1.1 christos { "threads", infpy_threads, METH_NOARGS, 1075 1.1 christos "Return all the threads of this inferior." }, 1076 1.1 christos { "read_memory", (PyCFunction) infpy_read_memory, 1077 1.1 christos METH_VARARGS | METH_KEYWORDS, 1078 1.1 christos "read_memory (address, length) -> buffer\n\ 1079 1.1 christos Return a buffer object for reading from the inferior's memory." }, 1080 1.1 christos { "write_memory", (PyCFunction) infpy_write_memory, 1081 1.1 christos METH_VARARGS | METH_KEYWORDS, 1082 1.1 christos "write_memory (address, buffer [, length])\n\ 1083 1.1 christos Write the given buffer object to the inferior's memory." }, 1084 1.1 christos { "search_memory", (PyCFunction) infpy_search_memory, 1085 1.1 christos METH_VARARGS | METH_KEYWORDS, 1086 1.1 christos "search_memory (address, length, pattern) -> long\n\ 1087 1.9 christos Return a long with the address of a match, or None." }, 1088 1.8 christos /* thread_from_thread_handle is deprecated. */ 1089 1.8 christos { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle, 1090 1.8 christos METH_VARARGS | METH_KEYWORDS, 1091 1.9 christos "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\ 1092 1.9 christos Return thread object corresponding to thread handle.\n\ 1093 1.9 christos This method is deprecated - use thread_from_handle instead." }, 1094 1.9 christos { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle, 1095 1.9 christos METH_VARARGS | METH_KEYWORDS, 1096 1.8 christos "thread_from_handle (handle) -> gdb.InferiorThread.\n\ 1097 1.8 christos Return thread object corresponding to thread handle." }, 1098 1.8 christos { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS, 1099 1.8 christos "architecture () -> gdb.Architecture\n\ 1100 1.11 christos Return architecture of this inferior." }, 1101 1.11 christos { "clear_env", (PyCFunction) infpy_clear_env, METH_NOARGS, 1102 1.11 christos "clear_env () -> None\n\ 1103 1.11 christos Clear environment of this inferior." }, 1104 1.11 christos { "set_env", (PyCFunction) infpy_set_env, METH_VARARGS | METH_KEYWORDS, 1105 1.11 christos "set_env (name, value) -> None\n\ 1106 1.11 christos Set an environment variable of this inferior." }, 1107 1.11 christos { "unset_env", (PyCFunction) infpy_unset_env, METH_VARARGS | METH_KEYWORDS, 1108 1.11 christos "unset_env (name) -> None\n\ 1109 1.1 christos Unset an environment of this inferior." }, 1110 1.1 christos { NULL } 1111 1.1 christos }; 1112 1.5 christos 1113 1.1 christos PyTypeObject inferior_object_type = 1114 1.1 christos { 1115 1.1 christos PyVarObject_HEAD_INIT (NULL, 0) 1116 1.1 christos "gdb.Inferior", /* tp_name */ 1117 1.1 christos sizeof (inferior_object), /* tp_basicsize */ 1118 1.1 christos 0, /* tp_itemsize */ 1119 1.1 christos infpy_dealloc, /* tp_dealloc */ 1120 1.1 christos 0, /* tp_print */ 1121 1.1 christos 0, /* tp_getattr */ 1122 1.1 christos 0, /* tp_setattr */ 1123 1.8 christos 0, /* tp_compare */ 1124 1.1 christos infpy_repr, /* tp_repr */ 1125 1.1 christos 0, /* tp_as_number */ 1126 1.1 christos 0, /* tp_as_sequence */ 1127 1.1 christos 0, /* tp_as_mapping */ 1128 1.1 christos 0, /* tp_hash */ 1129 1.1 christos 0, /* tp_call */ 1130 1.1 christos 0, /* tp_str */ 1131 1.1 christos 0, /* tp_getattro */ 1132 1.1 christos 0, /* tp_setattro */ 1133 1.10 christos 0, /* tp_as_buffer */ 1134 1.1 christos Py_TPFLAGS_DEFAULT, /* tp_flags */ 1135 1.1 christos "GDB inferior object", /* tp_doc */ 1136 1.1 christos 0, /* tp_traverse */ 1137 1.1 christos 0, /* tp_clear */ 1138 1.1 christos 0, /* tp_richcompare */ 1139 1.1 christos 0, /* tp_weaklistoffset */ 1140 1.1 christos 0, /* tp_iter */ 1141 1.1 christos 0, /* tp_iternext */ 1142 1.1 christos inferior_object_methods, /* tp_methods */ 1143 1.1 christos 0, /* tp_members */ 1144 1.1 christos inferior_object_getset, /* tp_getset */ 1145 1.1 christos 0, /* tp_base */ 1146 1.1 christos 0, /* tp_dict */ 1147 1.1 christos 0, /* tp_descr_get */ 1148 1.11 christos 0, /* tp_descr_set */ 1149 1.1 christos offsetof (inferior_object, dict), /* tp_dictoffset */ 1150 1.1 christos 0, /* tp_init */ 1151 1.1 christos 0 /* tp_alloc */ 1152 }; 1153