1/* Python interface to inferiors. 2 3 Copyright (C) 2009-2020 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "defs.h" 21#include "gdbcore.h" 22#include "gdbthread.h" 23#include "inferior.h" 24#include "objfiles.h" 25#include "observable.h" 26#include "python-internal.h" 27#include "arch-utils.h" 28#include "language.h" 29#include "gdbsupport/gdb_signals.h" 30#include "py-event.h" 31#include "py-stopevent.h" 32 33struct threadlist_entry 34{ 35 threadlist_entry (gdbpy_ref<thread_object> &&ref) 36 : thread_obj (std::move (ref)) 37 { 38 } 39 40 gdbpy_ref<thread_object> thread_obj; 41 struct threadlist_entry *next; 42}; 43 44struct inferior_object 45{ 46 PyObject_HEAD 47 48 /* The inferior we represent. */ 49 struct inferior *inferior; 50 51 /* thread_object instances under this inferior. This list owns a 52 reference to each object it contains. */ 53 struct threadlist_entry *threads; 54 55 /* Number of threads in the list. */ 56 int nthreads; 57}; 58 59extern PyTypeObject inferior_object_type 60 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object"); 61 62static const struct inferior_data *infpy_inf_data_key; 63 64typedef struct { 65 PyObject_HEAD 66 void *buffer; 67 68 /* These are kept just for mbpy_str. */ 69 CORE_ADDR addr; 70 CORE_ADDR length; 71} membuf_object; 72 73extern PyTypeObject membuf_object_type 74 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object"); 75 76/* Require that INFERIOR be a valid inferior ID. */ 77#define INFPY_REQUIRE_VALID(Inferior) \ 78 do { \ 79 if (!Inferior->inferior) \ 80 { \ 81 PyErr_SetString (PyExc_RuntimeError, \ 82 _("Inferior no longer exists.")); \ 83 return NULL; \ 84 } \ 85 } while (0) 86 87static void 88python_on_normal_stop (struct bpstats *bs, int print_frame) 89{ 90 enum gdb_signal stop_signal; 91 92 if (!gdb_python_initialized) 93 return; 94 95 if (inferior_ptid == null_ptid) 96 return; 97 98 stop_signal = inferior_thread ()->suspend.stop_signal; 99 100 gdbpy_enter enter_py (get_current_arch (), current_language); 101 102 if (emit_stop_event (bs, stop_signal) < 0) 103 gdbpy_print_stack (); 104} 105 106static void 107python_on_resume (ptid_t ptid) 108{ 109 if (!gdb_python_initialized) 110 return; 111 112 gdbpy_enter enter_py (target_gdbarch (), current_language); 113 114 if (emit_continue_event (ptid) < 0) 115 gdbpy_print_stack (); 116} 117 118/* Callback, registered as an observer, that notifies Python listeners 119 when an inferior function call is about to be made. */ 120 121static void 122python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address) 123{ 124 gdbpy_enter enter_py (target_gdbarch (), current_language); 125 126 if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0) 127 gdbpy_print_stack (); 128} 129 130/* Callback, registered as an observer, that notifies Python listeners 131 when an inferior function call has completed. */ 132 133static void 134python_on_inferior_call_post (ptid_t thread, CORE_ADDR address) 135{ 136 gdbpy_enter enter_py (target_gdbarch (), current_language); 137 138 if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0) 139 gdbpy_print_stack (); 140} 141 142/* Callback, registered as an observer, that notifies Python listeners 143 when a part of memory has been modified by user action (eg via a 144 'set' command). */ 145 146static void 147python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data) 148{ 149 gdbpy_enter enter_py (target_gdbarch (), current_language); 150 151 if (emit_memory_changed_event (addr, len) < 0) 152 gdbpy_print_stack (); 153} 154 155/* Callback, registered as an observer, that notifies Python listeners 156 when a register has been modified by user action (eg via a 'set' 157 command). */ 158 159static void 160python_on_register_change (struct frame_info *frame, int regnum) 161{ 162 gdbpy_enter enter_py (target_gdbarch (), current_language); 163 164 if (emit_register_changed_event (frame, regnum) < 0) 165 gdbpy_print_stack (); 166} 167 168static void 169python_inferior_exit (struct inferior *inf) 170{ 171 const LONGEST *exit_code = NULL; 172 173 if (!gdb_python_initialized) 174 return; 175 176 gdbpy_enter enter_py (target_gdbarch (), current_language); 177 178 if (inf->has_exit_code) 179 exit_code = &inf->exit_code; 180 181 if (emit_exited_event (exit_code, inf) < 0) 182 gdbpy_print_stack (); 183} 184 185/* Callback used to notify Python listeners about new objfiles loaded in the 186 inferior. OBJFILE may be NULL which means that the objfile list has been 187 cleared (emptied). */ 188 189static void 190python_new_objfile (struct objfile *objfile) 191{ 192 if (!gdb_python_initialized) 193 return; 194 195 gdbpy_enter enter_py (objfile != NULL 196 ? objfile->arch () 197 : target_gdbarch (), 198 current_language); 199 200 if (objfile == NULL) 201 { 202 if (emit_clear_objfiles_event () < 0) 203 gdbpy_print_stack (); 204 } 205 else 206 { 207 if (emit_new_objfile_event (objfile) < 0) 208 gdbpy_print_stack (); 209 } 210} 211 212/* Return a reference to the Python object of type Inferior 213 representing INFERIOR. If the object has already been created, 214 return it and increment the reference count, otherwise, create it. 215 Return NULL on failure. */ 216 217gdbpy_ref<inferior_object> 218inferior_to_inferior_object (struct inferior *inferior) 219{ 220 inferior_object *inf_obj; 221 222 inf_obj = (inferior_object *) inferior_data (inferior, infpy_inf_data_key); 223 if (!inf_obj) 224 { 225 inf_obj = PyObject_New (inferior_object, &inferior_object_type); 226 if (!inf_obj) 227 return NULL; 228 229 inf_obj->inferior = inferior; 230 inf_obj->threads = NULL; 231 inf_obj->nthreads = 0; 232 233 /* PyObject_New initializes the new object with a refcount of 1. This 234 counts for the reference we are keeping in the inferior data. */ 235 set_inferior_data (inferior, infpy_inf_data_key, inf_obj); 236 } 237 238 /* We are returning a new reference. */ 239 gdb_assert (inf_obj != nullptr); 240 return gdbpy_ref<inferior_object>::new_reference (inf_obj); 241} 242 243/* Called when a new inferior is created. Notifies any Python event 244 listeners. */ 245static void 246python_new_inferior (struct inferior *inf) 247{ 248 if (!gdb_python_initialized) 249 return; 250 251 gdbpy_enter enter_py (python_gdbarch, python_language); 252 253 if (evregpy_no_listeners_p (gdb_py_events.new_inferior)) 254 return; 255 256 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf); 257 if (inf_obj == NULL) 258 { 259 gdbpy_print_stack (); 260 return; 261 } 262 263 gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type); 264 if (event == NULL 265 || evpy_add_attribute (event.get (), "inferior", 266 (PyObject *) inf_obj.get ()) < 0 267 || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0) 268 gdbpy_print_stack (); 269} 270 271/* Called when an inferior is removed. Notifies any Python event 272 listeners. */ 273static void 274python_inferior_deleted (struct inferior *inf) 275{ 276 if (!gdb_python_initialized) 277 return; 278 279 gdbpy_enter enter_py (python_gdbarch, python_language); 280 281 if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted)) 282 return; 283 284 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf); 285 if (inf_obj == NULL) 286 { 287 gdbpy_print_stack (); 288 return; 289 } 290 291 gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type); 292 if (event == NULL 293 || evpy_add_attribute (event.get (), "inferior", 294 (PyObject *) inf_obj.get ()) < 0 295 || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0) 296 gdbpy_print_stack (); 297} 298 299gdbpy_ref<> 300thread_to_thread_object (thread_info *thr) 301{ 302 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf); 303 if (inf_obj == NULL) 304 return NULL; 305 306 for (threadlist_entry *thread = inf_obj->threads; 307 thread != NULL; 308 thread = thread->next) 309 if (thread->thread_obj->thread == thr) 310 return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj.get ()); 311 312 PyErr_SetString (PyExc_SystemError, 313 _("could not find gdb thread object")); 314 return NULL; 315} 316 317static void 318add_thread_object (struct thread_info *tp) 319{ 320 inferior_object *inf_obj; 321 struct threadlist_entry *entry; 322 323 if (!gdb_python_initialized) 324 return; 325 326 gdbpy_enter enter_py (python_gdbarch, python_language); 327 328 gdbpy_ref<thread_object> thread_obj = create_thread_object (tp); 329 if (thread_obj == NULL) 330 { 331 gdbpy_print_stack (); 332 return; 333 } 334 335 inf_obj = (inferior_object *) thread_obj->inf_obj; 336 337 entry = new threadlist_entry (std::move (thread_obj)); 338 entry->next = inf_obj->threads; 339 340 inf_obj->threads = entry; 341 inf_obj->nthreads++; 342 343 if (evregpy_no_listeners_p (gdb_py_events.new_thread)) 344 return; 345 346 gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type, 347 (PyObject *) inf_obj); 348 if (event == NULL 349 || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0) 350 gdbpy_print_stack (); 351} 352 353static void 354delete_thread_object (struct thread_info *tp, int ignore) 355{ 356 struct threadlist_entry **entry, *tmp; 357 358 if (!gdb_python_initialized) 359 return; 360 361 gdbpy_enter enter_py (python_gdbarch, python_language); 362 363 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf); 364 if (inf_obj == NULL) 365 return; 366 367 /* Find thread entry in its inferior's thread_list. */ 368 for (entry = &inf_obj->threads; *entry != NULL; entry = 369 &(*entry)->next) 370 if ((*entry)->thread_obj->thread == tp) 371 break; 372 373 if (!*entry) 374 return; 375 376 tmp = *entry; 377 tmp->thread_obj->thread = NULL; 378 379 *entry = (*entry)->next; 380 inf_obj->nthreads--; 381 382 delete tmp; 383} 384 385static PyObject * 386infpy_threads (PyObject *self, PyObject *args) 387{ 388 int i; 389 struct threadlist_entry *entry; 390 inferior_object *inf_obj = (inferior_object *) self; 391 PyObject *tuple; 392 393 INFPY_REQUIRE_VALID (inf_obj); 394 395 try 396 { 397 update_thread_list (); 398 } 399 catch (const gdb_exception &except) 400 { 401 GDB_PY_HANDLE_EXCEPTION (except); 402 } 403 404 tuple = PyTuple_New (inf_obj->nthreads); 405 if (!tuple) 406 return NULL; 407 408 for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads; 409 i++, entry = entry->next) 410 { 411 PyObject *thr = (PyObject *) entry->thread_obj.get (); 412 Py_INCREF (thr); 413 PyTuple_SET_ITEM (tuple, i, thr); 414 } 415 416 return tuple; 417} 418 419static PyObject * 420infpy_get_num (PyObject *self, void *closure) 421{ 422 inferior_object *inf = (inferior_object *) self; 423 424 INFPY_REQUIRE_VALID (inf); 425 426 return PyLong_FromLong (inf->inferior->num); 427} 428 429static PyObject * 430infpy_get_pid (PyObject *self, void *closure) 431{ 432 inferior_object *inf = (inferior_object *) self; 433 434 INFPY_REQUIRE_VALID (inf); 435 436 return PyLong_FromLong (inf->inferior->pid); 437} 438 439static PyObject * 440infpy_get_was_attached (PyObject *self, void *closure) 441{ 442 inferior_object *inf = (inferior_object *) self; 443 444 INFPY_REQUIRE_VALID (inf); 445 if (inf->inferior->attach_flag) 446 Py_RETURN_TRUE; 447 Py_RETURN_FALSE; 448} 449 450/* Getter of gdb.Inferior.progspace. */ 451 452static PyObject * 453infpy_get_progspace (PyObject *self, void *closure) 454{ 455 inferior_object *inf = (inferior_object *) self; 456 457 INFPY_REQUIRE_VALID (inf); 458 459 program_space *pspace = inf->inferior->pspace; 460 gdb_assert (pspace != nullptr); 461 462 return pspace_to_pspace_object (pspace).release (); 463} 464 465/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). 466 Returns a tuple of all inferiors. */ 467PyObject * 468gdbpy_inferiors (PyObject *unused, PyObject *unused2) 469{ 470 gdbpy_ref<> list (PyList_New (0)); 471 if (list == NULL) 472 return NULL; 473 474 for (inferior *inf : all_inferiors ()) 475 { 476 gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf); 477 478 if (inferior == NULL) 479 continue; 480 481 if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0) 482 return NULL; 483 } 484 485 return PyList_AsTuple (list.get ()); 486} 487 488/* Membuf and memory manipulation. */ 489 490/* Implementation of Inferior.read_memory (address, length). 491 Returns a Python buffer object with LENGTH bytes of the inferior's 492 memory at ADDRESS. Both arguments are integers. Returns NULL on error, 493 with a python exception set. */ 494static PyObject * 495infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw) 496{ 497 CORE_ADDR addr, length; 498 gdb::unique_xmalloc_ptr<gdb_byte> buffer; 499 PyObject *addr_obj, *length_obj, *result; 500 static const char *keywords[] = { "address", "length", NULL }; 501 502 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords, 503 &addr_obj, &length_obj)) 504 return NULL; 505 506 if (get_addr_from_python (addr_obj, &addr) < 0 507 || get_addr_from_python (length_obj, &length) < 0) 508 return NULL; 509 510 try 511 { 512 buffer.reset ((gdb_byte *) xmalloc (length)); 513 514 read_memory (addr, buffer.get (), length); 515 } 516 catch (const gdb_exception &except) 517 { 518 GDB_PY_HANDLE_EXCEPTION (except); 519 } 520 521 gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object, 522 &membuf_object_type)); 523 if (membuf_obj == NULL) 524 return NULL; 525 526 membuf_obj->buffer = buffer.release (); 527 membuf_obj->addr = addr; 528 membuf_obj->length = length; 529 530#ifdef IS_PY3K 531 result = PyMemoryView_FromObject ((PyObject *) membuf_obj.get ()); 532#else 533 result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj.get (), 0, 534 Py_END_OF_BUFFER); 535#endif 536 537 return result; 538} 539 540/* Implementation of Inferior.write_memory (address, buffer [, length]). 541 Writes the contents of BUFFER (a Python object supporting the read 542 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH 543 bytes from BUFFER, or its entire contents if the argument is not 544 provided. The function returns nothing. Returns NULL on error, with 545 a python exception set. */ 546static PyObject * 547infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw) 548{ 549 struct gdb_exception except; 550 Py_ssize_t buf_len; 551 const gdb_byte *buffer; 552 CORE_ADDR addr, length; 553 PyObject *addr_obj, *length_obj = NULL; 554 static const char *keywords[] = { "address", "buffer", "length", NULL }; 555 Py_buffer pybuf; 556 557 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords, 558 &addr_obj, &pybuf, &length_obj)) 559 return NULL; 560 561 Py_buffer_up buffer_up (&pybuf); 562 buffer = (const gdb_byte *) pybuf.buf; 563 buf_len = pybuf.len; 564 565 if (get_addr_from_python (addr_obj, &addr) < 0) 566 return nullptr; 567 568 if (!length_obj) 569 length = buf_len; 570 else if (get_addr_from_python (length_obj, &length) < 0) 571 return nullptr; 572 573 try 574 { 575 write_memory_with_notification (addr, buffer, length); 576 } 577 catch (gdb_exception &ex) 578 { 579 except = std::move (ex); 580 } 581 582 GDB_PY_HANDLE_EXCEPTION (except); 583 584 Py_RETURN_NONE; 585} 586 587/* Destructor of Membuf objects. */ 588static void 589mbpy_dealloc (PyObject *self) 590{ 591 xfree (((membuf_object *) self)->buffer); 592 Py_TYPE (self)->tp_free (self); 593} 594 595/* Return a description of the Membuf object. */ 596static PyObject * 597mbpy_str (PyObject *self) 598{ 599 membuf_object *membuf_obj = (membuf_object *) self; 600 601 return PyString_FromFormat (_("Memory buffer for address %s, \ 602which is %s bytes long."), 603 paddress (python_gdbarch, membuf_obj->addr), 604 pulongest (membuf_obj->length)); 605} 606 607#ifdef IS_PY3K 608 609static int 610get_buffer (PyObject *self, Py_buffer *buf, int flags) 611{ 612 membuf_object *membuf_obj = (membuf_object *) self; 613 int ret; 614 615 ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer, 616 membuf_obj->length, 0, 617 PyBUF_CONTIG); 618 619 /* Despite the documentation saying this field is a "const char *", 620 in Python 3.4 at least, it's really a "char *". */ 621 buf->format = (char *) "c"; 622 623 return ret; 624} 625 626#else 627 628static Py_ssize_t 629get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) 630{ 631 membuf_object *membuf_obj = (membuf_object *) self; 632 633 if (segment) 634 { 635 PyErr_SetString (PyExc_SystemError, 636 _("The memory buffer supports only one segment.")); 637 return -1; 638 } 639 640 *ptrptr = membuf_obj->buffer; 641 642 return membuf_obj->length; 643} 644 645static Py_ssize_t 646get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) 647{ 648 return get_read_buffer (self, segment, ptrptr); 649} 650 651static Py_ssize_t 652get_seg_count (PyObject *self, Py_ssize_t *lenp) 653{ 654 if (lenp) 655 *lenp = ((membuf_object *) self)->length; 656 657 return 1; 658} 659 660static Py_ssize_t 661get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr) 662{ 663 void *ptr = NULL; 664 Py_ssize_t ret; 665 666 ret = get_read_buffer (self, segment, &ptr); 667 *ptrptr = (char *) ptr; 668 669 return ret; 670} 671 672#endif /* IS_PY3K */ 673 674/* Implementation of 675 gdb.search_memory (address, length, pattern). ADDRESS is the 676 address to start the search. LENGTH specifies the scope of the 677 search from ADDRESS. PATTERN is the pattern to search for (and 678 must be a Python object supporting the buffer protocol). 679 Returns a Python Long object holding the address where the pattern 680 was located, or if the pattern was not found, returns None. Returns NULL 681 on error, with a python exception set. */ 682static PyObject * 683infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) 684{ 685 struct gdb_exception except; 686 CORE_ADDR start_addr, length; 687 static const char *keywords[] = { "address", "length", "pattern", NULL }; 688 PyObject *start_addr_obj, *length_obj; 689 Py_ssize_t pattern_size; 690 const gdb_byte *buffer; 691 CORE_ADDR found_addr; 692 int found = 0; 693 Py_buffer pybuf; 694 695 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords, 696 &start_addr_obj, &length_obj, 697 &pybuf)) 698 return NULL; 699 700 Py_buffer_up buffer_up (&pybuf); 701 buffer = (const gdb_byte *) pybuf.buf; 702 pattern_size = pybuf.len; 703 704 if (get_addr_from_python (start_addr_obj, &start_addr) < 0) 705 return nullptr; 706 707 if (get_addr_from_python (length_obj, &length) < 0) 708 return nullptr; 709 710 if (!length) 711 { 712 PyErr_SetString (PyExc_ValueError, 713 _("Search range is empty.")); 714 return nullptr; 715 } 716 /* Watch for overflows. */ 717 else if (length > CORE_ADDR_MAX 718 || (start_addr + length - 1) < start_addr) 719 { 720 PyErr_SetString (PyExc_ValueError, 721 _("The search range is too large.")); 722 return nullptr; 723 } 724 725 try 726 { 727 found = target_search_memory (start_addr, length, 728 buffer, pattern_size, 729 &found_addr); 730 } 731 catch (gdb_exception &ex) 732 { 733 except = std::move (ex); 734 } 735 736 GDB_PY_HANDLE_EXCEPTION (except); 737 738 if (found) 739 return gdb_py_object_from_ulongest (found_addr).release (); 740 else 741 Py_RETURN_NONE; 742} 743 744/* Implementation of gdb.Inferior.is_valid (self) -> Boolean. 745 Returns True if this inferior object still exists in GDB. */ 746 747static PyObject * 748infpy_is_valid (PyObject *self, PyObject *args) 749{ 750 inferior_object *inf = (inferior_object *) self; 751 752 if (! inf->inferior) 753 Py_RETURN_FALSE; 754 755 Py_RETURN_TRUE; 756} 757 758/* Implementation of gdb.Inferior.thread_from_handle (self, handle) 759 -> gdb.InferiorThread. */ 760 761static PyObject * 762infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw) 763{ 764 PyObject *handle_obj; 765 inferior_object *inf_obj = (inferior_object *) self; 766 static const char *keywords[] = { "handle", NULL }; 767 768 INFPY_REQUIRE_VALID (inf_obj); 769 770 if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj)) 771 return NULL; 772 773 const gdb_byte *bytes; 774 size_t bytes_len; 775 Py_buffer_up buffer_up; 776 Py_buffer py_buf; 777 778 if (PyObject_CheckBuffer (handle_obj) 779 && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0) 780 { 781 buffer_up.reset (&py_buf); 782 bytes = (const gdb_byte *) py_buf.buf; 783 bytes_len = py_buf.len; 784 } 785 else if (gdbpy_is_value_object (handle_obj)) 786 { 787 struct value *val = value_object_to_value (handle_obj); 788 bytes = value_contents_all (val); 789 bytes_len = TYPE_LENGTH (value_type (val)); 790 } 791 else 792 { 793 PyErr_SetString (PyExc_TypeError, 794 _("Argument 'handle' must be a thread handle object.")); 795 796 return NULL; 797 } 798 799 try 800 { 801 struct thread_info *thread_info; 802 803 thread_info = find_thread_by_handle 804 (gdb::array_view<const gdb_byte> (bytes, bytes_len), 805 inf_obj->inferior); 806 if (thread_info != NULL) 807 return thread_to_thread_object (thread_info).release (); 808 } 809 catch (const gdb_exception &except) 810 { 811 GDB_PY_HANDLE_EXCEPTION (except); 812 } 813 814 Py_RETURN_NONE; 815} 816 817/* Implementation of gdb.Inferior.architecture. */ 818 819static PyObject * 820infpy_architecture (PyObject *self, PyObject *args) 821{ 822 inferior_object *inf = (inferior_object *) self; 823 824 INFPY_REQUIRE_VALID (inf); 825 826 return gdbarch_to_arch_object (inf->inferior->gdbarch); 827} 828 829/* Implement repr() for gdb.Inferior. */ 830 831static PyObject * 832infpy_repr (PyObject *obj) 833{ 834 inferior_object *self = (inferior_object *) obj; 835 inferior *inf = self->inferior; 836 837 if (inf == nullptr) 838 return PyString_FromString ("<gdb.Inferior (invalid)>"); 839 840 return PyString_FromFormat ("<gdb.Inferior num=%d, pid=%d>", 841 inf->num, inf->pid); 842} 843 844 845static void 846infpy_dealloc (PyObject *obj) 847{ 848 inferior_object *inf_obj = (inferior_object *) obj; 849 struct inferior *inf = inf_obj->inferior; 850 851 if (! inf) 852 return; 853 854 set_inferior_data (inf, infpy_inf_data_key, NULL); 855 Py_TYPE (obj)->tp_free (obj); 856} 857 858/* Clear the INFERIOR pointer in an Inferior object and clear the 859 thread list. */ 860static void 861py_free_inferior (struct inferior *inf, void *datum) 862{ 863 struct threadlist_entry *th_entry, *th_tmp; 864 865 if (!gdb_python_initialized) 866 return; 867 868 gdbpy_enter enter_py (python_gdbarch, python_language); 869 gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum); 870 871 inf_obj->inferior = NULL; 872 873 /* Deallocate threads list. */ 874 for (th_entry = inf_obj->threads; th_entry != NULL;) 875 { 876 th_tmp = th_entry; 877 th_entry = th_entry->next; 878 delete th_tmp; 879 } 880 881 inf_obj->nthreads = 0; 882} 883 884/* Implementation of gdb.selected_inferior() -> gdb.Inferior. 885 Returns the current inferior object. */ 886 887PyObject * 888gdbpy_selected_inferior (PyObject *self, PyObject *args) 889{ 890 return ((PyObject *) 891 inferior_to_inferior_object (current_inferior ()).release ()); 892} 893 894int 895gdbpy_initialize_inferior (void) 896{ 897 if (PyType_Ready (&inferior_object_type) < 0) 898 return -1; 899 900 if (gdb_pymodule_addobject (gdb_module, "Inferior", 901 (PyObject *) &inferior_object_type) < 0) 902 return -1; 903 904 infpy_inf_data_key = 905 register_inferior_data_with_cleanup (NULL, py_free_inferior); 906 907 gdb::observers::new_thread.attach (add_thread_object); 908 gdb::observers::thread_exit.attach (delete_thread_object); 909 gdb::observers::normal_stop.attach (python_on_normal_stop); 910 gdb::observers::target_resumed.attach (python_on_resume); 911 gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre); 912 gdb::observers::inferior_call_post.attach (python_on_inferior_call_post); 913 gdb::observers::memory_changed.attach (python_on_memory_change); 914 gdb::observers::register_changed.attach (python_on_register_change); 915 gdb::observers::inferior_exit.attach (python_inferior_exit); 916 gdb::observers::new_objfile.attach (python_new_objfile); 917 gdb::observers::inferior_added.attach (python_new_inferior); 918 gdb::observers::inferior_removed.attach (python_inferior_deleted); 919 920 membuf_object_type.tp_new = PyType_GenericNew; 921 if (PyType_Ready (&membuf_object_type) < 0) 922 return -1; 923 924 return gdb_pymodule_addobject (gdb_module, "Membuf", 925 (PyObject *) &membuf_object_type); 926} 927 928static gdb_PyGetSetDef inferior_object_getset[] = 929{ 930 { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL }, 931 { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.", 932 NULL }, 933 { "was_attached", infpy_get_was_attached, NULL, 934 "True if the inferior was created using 'attach'.", NULL }, 935 { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" }, 936 { NULL } 937}; 938 939static PyMethodDef inferior_object_methods[] = 940{ 941 { "is_valid", infpy_is_valid, METH_NOARGS, 942 "is_valid () -> Boolean.\n\ 943Return true if this inferior is valid, false if not." }, 944 { "threads", infpy_threads, METH_NOARGS, 945 "Return all the threads of this inferior." }, 946 { "read_memory", (PyCFunction) infpy_read_memory, 947 METH_VARARGS | METH_KEYWORDS, 948 "read_memory (address, length) -> buffer\n\ 949Return a buffer object for reading from the inferior's memory." }, 950 { "write_memory", (PyCFunction) infpy_write_memory, 951 METH_VARARGS | METH_KEYWORDS, 952 "write_memory (address, buffer [, length])\n\ 953Write the given buffer object to the inferior's memory." }, 954 { "search_memory", (PyCFunction) infpy_search_memory, 955 METH_VARARGS | METH_KEYWORDS, 956 "search_memory (address, length, pattern) -> long\n\ 957Return a long with the address of a match, or None." }, 958 /* thread_from_thread_handle is deprecated. */ 959 { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle, 960 METH_VARARGS | METH_KEYWORDS, 961 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\ 962Return thread object corresponding to thread handle.\n\ 963This method is deprecated - use thread_from_handle instead." }, 964 { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle, 965 METH_VARARGS | METH_KEYWORDS, 966 "thread_from_handle (handle) -> gdb.InferiorThread.\n\ 967Return thread object corresponding to thread handle." }, 968 { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS, 969 "architecture () -> gdb.Architecture\n\ 970Return architecture of this inferior." }, 971 { NULL } 972}; 973 974PyTypeObject inferior_object_type = 975{ 976 PyVarObject_HEAD_INIT (NULL, 0) 977 "gdb.Inferior", /* tp_name */ 978 sizeof (inferior_object), /* tp_basicsize */ 979 0, /* tp_itemsize */ 980 infpy_dealloc, /* tp_dealloc */ 981 0, /* tp_print */ 982 0, /* tp_getattr */ 983 0, /* tp_setattr */ 984 0, /* tp_compare */ 985 infpy_repr, /* tp_repr */ 986 0, /* tp_as_number */ 987 0, /* tp_as_sequence */ 988 0, /* tp_as_mapping */ 989 0, /* tp_hash */ 990 0, /* tp_call */ 991 0, /* tp_str */ 992 0, /* tp_getattro */ 993 0, /* tp_setattro */ 994 0, /* tp_as_buffer */ 995 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ 996 "GDB inferior object", /* tp_doc */ 997 0, /* tp_traverse */ 998 0, /* tp_clear */ 999 0, /* tp_richcompare */ 1000 0, /* tp_weaklistoffset */ 1001 0, /* tp_iter */ 1002 0, /* tp_iternext */ 1003 inferior_object_methods, /* tp_methods */ 1004 0, /* tp_members */ 1005 inferior_object_getset, /* tp_getset */ 1006 0, /* tp_base */ 1007 0, /* tp_dict */ 1008 0, /* tp_descr_get */ 1009 0, /* tp_descr_set */ 1010 0, /* tp_dictoffset */ 1011 0, /* tp_init */ 1012 0 /* tp_alloc */ 1013}; 1014 1015#ifdef IS_PY3K 1016 1017static PyBufferProcs buffer_procs = 1018{ 1019 get_buffer 1020}; 1021 1022#else 1023 1024static PyBufferProcs buffer_procs = { 1025 get_read_buffer, 1026 get_write_buffer, 1027 get_seg_count, 1028 get_char_buffer 1029}; 1030#endif /* IS_PY3K */ 1031 1032PyTypeObject membuf_object_type = { 1033 PyVarObject_HEAD_INIT (NULL, 0) 1034 "gdb.Membuf", /*tp_name*/ 1035 sizeof (membuf_object), /*tp_basicsize*/ 1036 0, /*tp_itemsize*/ 1037 mbpy_dealloc, /*tp_dealloc*/ 1038 0, /*tp_print*/ 1039 0, /*tp_getattr*/ 1040 0, /*tp_setattr*/ 1041 0, /*tp_compare*/ 1042 0, /*tp_repr*/ 1043 0, /*tp_as_number*/ 1044 0, /*tp_as_sequence*/ 1045 0, /*tp_as_mapping*/ 1046 0, /*tp_hash */ 1047 0, /*tp_call*/ 1048 mbpy_str, /*tp_str*/ 1049 0, /*tp_getattro*/ 1050 0, /*tp_setattro*/ 1051 &buffer_procs, /*tp_as_buffer*/ 1052 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1053 "GDB memory buffer object", /*tp_doc*/ 1054 0, /* tp_traverse */ 1055 0, /* tp_clear */ 1056 0, /* tp_richcompare */ 1057 0, /* tp_weaklistoffset */ 1058 0, /* tp_iter */ 1059 0, /* tp_iternext */ 1060 0, /* tp_methods */ 1061 0, /* tp_members */ 1062 0, /* tp_getset */ 1063 0, /* tp_base */ 1064 0, /* tp_dict */ 1065 0, /* tp_descr_get */ 1066 0, /* tp_descr_set */ 1067 0, /* tp_dictoffset */ 1068 0, /* tp_init */ 1069 0, /* tp_alloc */ 1070}; 1071