GDB (API)
/home/stan/gdb/src/gdb/python/py-inferior.c
Go to the documentation of this file.
00001 /* Python interface to inferiors.
00002 
00003    Copyright (C) 2009-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "exceptions.h"
00022 #include "gdbcore.h"
00023 #include "gdbthread.h"
00024 #include "inferior.h"
00025 #include "objfiles.h"
00026 #include "observer.h"
00027 #include "python-internal.h"
00028 #include "arch-utils.h"
00029 #include "language.h"
00030 #include "gdb_signals.h"
00031 #include "py-event.h"
00032 #include "py-stopevent.h"
00033 
00034 struct threadlist_entry {
00035   thread_object *thread_obj;
00036   struct threadlist_entry *next;
00037 };
00038 
00039 typedef struct
00040 {
00041   PyObject_HEAD
00042 
00043   /* The inferior we represent.  */
00044   struct inferior *inferior;
00045 
00046   /* thread_object instances under this inferior.  This list owns a
00047      reference to each object it contains.  */
00048   struct threadlist_entry *threads;
00049 
00050   /* Number of threads in the list.  */
00051   int nthreads;
00052 } inferior_object;
00053 
00054 static PyTypeObject inferior_object_type
00055     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
00056 
00057 static const struct inferior_data *infpy_inf_data_key;
00058 
00059 typedef struct {
00060   PyObject_HEAD
00061   void *buffer;
00062 
00063   /* These are kept just for mbpy_str.  */
00064   CORE_ADDR addr;
00065   CORE_ADDR length;
00066 } membuf_object;
00067 
00068 static PyTypeObject membuf_object_type
00069     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
00070 
00071 /* Require that INFERIOR be a valid inferior ID.  */
00072 #define INFPY_REQUIRE_VALID(Inferior)                           \
00073   do {                                                          \
00074     if (!Inferior->inferior)                                    \
00075       {                                                         \
00076         PyErr_SetString (PyExc_RuntimeError,                    \
00077                          _("Inferior no longer exists."));      \
00078         return NULL;                                            \
00079       }                                                         \
00080   } while (0)
00081 
00082 static void
00083 python_on_normal_stop (struct bpstats *bs, int print_frame)
00084 {
00085   struct cleanup *cleanup;
00086   enum gdb_signal stop_signal;
00087 
00088   if (!gdb_python_initialized)
00089     return;
00090 
00091   if (!find_thread_ptid (inferior_ptid))
00092       return;
00093 
00094   stop_signal = inferior_thread ()->suspend.stop_signal;
00095 
00096   cleanup = ensure_python_env (get_current_arch (), current_language);
00097 
00098   if (emit_stop_event (bs, stop_signal) < 0)
00099     gdbpy_print_stack ();
00100 
00101   do_cleanups (cleanup);
00102 }
00103 
00104 static void
00105 python_on_resume (ptid_t ptid)
00106 {
00107   struct cleanup *cleanup;
00108 
00109   if (!gdb_python_initialized)
00110     return;
00111 
00112   cleanup = ensure_python_env (target_gdbarch (), current_language);
00113 
00114   if (emit_continue_event (ptid) < 0)
00115     gdbpy_print_stack ();
00116 
00117   do_cleanups (cleanup);
00118 }
00119 
00120 static void
00121 python_inferior_exit (struct inferior *inf)
00122 {
00123   struct cleanup *cleanup;
00124   const LONGEST *exit_code = NULL;
00125 
00126   if (!gdb_python_initialized)
00127     return;
00128 
00129   cleanup = ensure_python_env (target_gdbarch (), current_language);
00130 
00131   if (inf->has_exit_code)
00132     exit_code = &inf->exit_code;
00133 
00134   if (emit_exited_event (exit_code, inf) < 0)
00135     gdbpy_print_stack ();
00136 
00137   do_cleanups (cleanup);
00138 }
00139 
00140 /* Callback used to notify Python listeners about new objfiles loaded in the
00141    inferior.  */
00142 
00143 static void
00144 python_new_objfile (struct objfile *objfile)
00145 {
00146   struct cleanup *cleanup;
00147 
00148   if (objfile == NULL)
00149     return;
00150 
00151   if (!gdb_python_initialized)
00152     return;
00153 
00154   cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
00155 
00156   if (emit_new_objfile_event (objfile) < 0)
00157     gdbpy_print_stack ();
00158 
00159   do_cleanups (cleanup);
00160 }
00161 
00162 /* Return a reference to the Python object of type Inferior
00163    representing INFERIOR.  If the object has already been created,
00164    return it and increment the reference count,  otherwise, create it.
00165    Return NULL on failure.  */
00166 PyObject *
00167 inferior_to_inferior_object (struct inferior *inferior)
00168 {
00169   inferior_object *inf_obj;
00170 
00171   inf_obj = inferior_data (inferior, infpy_inf_data_key);
00172   if (!inf_obj)
00173     {
00174       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
00175       if (!inf_obj)
00176           return NULL;
00177 
00178       inf_obj->inferior = inferior;
00179       inf_obj->threads = NULL;
00180       inf_obj->nthreads = 0;
00181 
00182       set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
00183 
00184     }
00185   else
00186     Py_INCREF ((PyObject *)inf_obj);
00187 
00188   return (PyObject *) inf_obj;
00189 }
00190 
00191 /* Finds the Python Inferior object for the given PID.  Returns a
00192    reference, or NULL if PID does not match any inferior object. */
00193 
00194 PyObject *
00195 find_inferior_object (int pid)
00196 {
00197   struct inferior *inf = find_inferior_pid (pid);
00198 
00199   if (inf)
00200     return inferior_to_inferior_object (inf);
00201 
00202   return NULL;
00203 }
00204 
00205 thread_object *
00206 find_thread_object (ptid_t ptid)
00207 {
00208   int pid;
00209   struct threadlist_entry *thread;
00210   PyObject *inf_obj;
00211   thread_object *found = NULL;
00212 
00213   pid = ptid_get_pid (ptid);
00214   if (pid == 0)
00215     return NULL;
00216 
00217   inf_obj = find_inferior_object (pid);
00218 
00219   if (! inf_obj)
00220     return NULL;
00221 
00222   for (thread = ((inferior_object *)inf_obj)->threads; thread;
00223        thread = thread->next)
00224     if (ptid_equal (thread->thread_obj->thread->ptid, ptid))
00225       {
00226         found = thread->thread_obj;
00227         break;
00228       }
00229 
00230   Py_DECREF (inf_obj);
00231 
00232   if (found)
00233     return found;
00234 
00235   return NULL;
00236 }
00237 
00238 static void
00239 add_thread_object (struct thread_info *tp)
00240 {
00241   struct cleanup *cleanup;
00242   thread_object *thread_obj;
00243   inferior_object *inf_obj;
00244   struct threadlist_entry *entry;
00245 
00246   if (!gdb_python_initialized)
00247     return;
00248 
00249   cleanup = ensure_python_env (python_gdbarch, python_language);
00250 
00251   thread_obj = create_thread_object (tp);
00252   if (!thread_obj)
00253     {
00254       gdbpy_print_stack ();
00255       do_cleanups (cleanup);
00256       return;
00257     }
00258 
00259   inf_obj = (inferior_object *) thread_obj->inf_obj;
00260 
00261   entry = xmalloc (sizeof (struct threadlist_entry));
00262   entry->thread_obj = thread_obj;
00263   entry->next = inf_obj->threads;
00264 
00265   inf_obj->threads = entry;
00266   inf_obj->nthreads++;
00267 
00268   do_cleanups (cleanup);
00269 }
00270 
00271 static void
00272 delete_thread_object (struct thread_info *tp, int ignore)
00273 {
00274   struct cleanup *cleanup;
00275   inferior_object *inf_obj;
00276   struct threadlist_entry **entry, *tmp;
00277   
00278   if (!gdb_python_initialized)
00279     return;
00280 
00281   cleanup = ensure_python_env (python_gdbarch, python_language);
00282 
00283   inf_obj
00284     = (inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid));
00285   if (!inf_obj)
00286     {
00287       do_cleanups (cleanup);
00288       return;
00289     }
00290 
00291   /* Find thread entry in its inferior's thread_list.  */
00292   for (entry = &inf_obj->threads; *entry != NULL; entry =
00293          &(*entry)->next)
00294     if ((*entry)->thread_obj->thread == tp)
00295       break;
00296 
00297   if (!*entry)
00298     {
00299       Py_DECREF (inf_obj);
00300       do_cleanups (cleanup);
00301       return;
00302     }
00303 
00304   tmp = *entry;
00305   tmp->thread_obj->thread = NULL;
00306 
00307   *entry = (*entry)->next;
00308   inf_obj->nthreads--;
00309 
00310   Py_DECREF (tmp->thread_obj);
00311   Py_DECREF (inf_obj);
00312   xfree (tmp);
00313 
00314   do_cleanups (cleanup);
00315 }
00316 
00317 static PyObject *
00318 infpy_threads (PyObject *self, PyObject *args)
00319 {
00320   int i;
00321   struct threadlist_entry *entry;
00322   inferior_object *inf_obj = (inferior_object *) self;
00323   PyObject *tuple;
00324   volatile struct gdb_exception except;
00325 
00326   INFPY_REQUIRE_VALID (inf_obj);
00327 
00328   TRY_CATCH (except, RETURN_MASK_ALL)
00329     update_thread_list ();
00330   GDB_PY_HANDLE_EXCEPTION (except);
00331 
00332   tuple = PyTuple_New (inf_obj->nthreads);
00333   if (!tuple)
00334     return NULL;
00335 
00336   for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
00337        i++, entry = entry->next)
00338     {
00339       Py_INCREF (entry->thread_obj);
00340       PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj);
00341     }
00342 
00343   return tuple;
00344 }
00345 
00346 static PyObject *
00347 infpy_get_num (PyObject *self, void *closure)
00348 {
00349   inferior_object *inf = (inferior_object *) self;
00350 
00351   INFPY_REQUIRE_VALID (inf);
00352 
00353   return PyLong_FromLong (inf->inferior->num);
00354 }
00355 
00356 static PyObject *
00357 infpy_get_pid (PyObject *self, void *closure)
00358 {
00359   inferior_object *inf = (inferior_object *) self;
00360 
00361   INFPY_REQUIRE_VALID (inf);
00362 
00363   return PyLong_FromLong (inf->inferior->pid);
00364 }
00365 
00366 static PyObject *
00367 infpy_get_was_attached (PyObject *self, void *closure)
00368 {
00369   inferior_object *inf = (inferior_object *) self;
00370 
00371   INFPY_REQUIRE_VALID (inf);
00372   if (inf->inferior->attach_flag)
00373     Py_RETURN_TRUE;
00374   Py_RETURN_FALSE;
00375 }
00376 
00377 static int
00378 build_inferior_list (struct inferior *inf, void *arg)
00379 {
00380   PyObject *list = arg;
00381   PyObject *inferior = inferior_to_inferior_object (inf);
00382   int success = 0;
00383 
00384   if (! inferior)
00385     return 0;
00386 
00387   success = PyList_Append (list, inferior);
00388   Py_DECREF (inferior);
00389 
00390   if (success)
00391     return 1;
00392 
00393   return 0;
00394 }
00395 
00396 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
00397    Returns a tuple of all inferiors.  */
00398 PyObject *
00399 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
00400 {
00401   PyObject *list, *tuple;
00402 
00403   list = PyList_New (0);
00404   if (!list)
00405     return NULL;
00406 
00407   if (iterate_over_inferiors (build_inferior_list, list))
00408     {
00409       Py_DECREF (list);
00410       return NULL;
00411     }
00412 
00413   tuple = PyList_AsTuple (list);
00414   Py_DECREF (list);
00415 
00416   return tuple;
00417 }
00418 
00419 /* Membuf and memory manipulation.  */
00420 
00421 /* Implementation of Inferior.read_memory (address, length).
00422    Returns a Python buffer object with LENGTH bytes of the inferior's
00423    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
00424    with a python exception set.  */
00425 static PyObject *
00426 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
00427 {
00428   CORE_ADDR addr, length;
00429   void *buffer = NULL;
00430   membuf_object *membuf_obj;
00431   PyObject *addr_obj, *length_obj, *result;
00432   volatile struct gdb_exception except;
00433   static char *keywords[] = { "address", "length", NULL };
00434 
00435   if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
00436                                      &addr_obj, &length_obj))
00437     return NULL;
00438 
00439   if (get_addr_from_python (addr_obj, &addr) < 0
00440       || get_addr_from_python (length_obj, &length) < 0)
00441     return NULL;
00442 
00443   TRY_CATCH (except, RETURN_MASK_ALL)
00444     {
00445       buffer = xmalloc (length);
00446 
00447       read_memory (addr, buffer, length);
00448     }
00449   if (except.reason < 0)
00450     {
00451       xfree (buffer);
00452       GDB_PY_HANDLE_EXCEPTION (except);
00453     }
00454 
00455   membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
00456   if (membuf_obj == NULL)
00457     {
00458       xfree (buffer);
00459       return NULL;
00460     }
00461 
00462   membuf_obj->buffer = buffer;
00463   membuf_obj->addr = addr;
00464   membuf_obj->length = length;
00465 
00466 #ifdef IS_PY3K
00467   result = PyMemoryView_FromObject ((PyObject *) membuf_obj);
00468 #else
00469   result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
00470                                          Py_END_OF_BUFFER);
00471 #endif
00472   Py_DECREF (membuf_obj);
00473 
00474   return result;
00475 }
00476 
00477 /* Implementation of Inferior.write_memory (address, buffer [, length]).
00478    Writes the contents of BUFFER (a Python object supporting the read
00479    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
00480    bytes from BUFFER, or its entire contents if the argument is not
00481    provided.  The function returns nothing.  Returns NULL on error, with
00482    a python exception set.  */
00483 static PyObject *
00484 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
00485 {
00486   Py_ssize_t buf_len;
00487   const char *buffer;
00488   CORE_ADDR addr, length;
00489   PyObject *addr_obj, *length_obj = NULL;
00490   volatile struct gdb_exception except;
00491   static char *keywords[] = { "address", "buffer", "length", NULL };
00492 #ifdef IS_PY3K
00493   Py_buffer pybuf;
00494 
00495   if (! PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
00496                                      &addr_obj, &pybuf,
00497                                      &length_obj))
00498     return NULL;
00499 
00500   buffer = pybuf.buf;
00501   buf_len = pybuf.len;
00502 #else
00503   if (! PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords,
00504                                      &addr_obj, &buffer, &buf_len,
00505                                      &length_obj))
00506     return NULL;
00507 #endif
00508 
00509   if (get_addr_from_python (addr_obj, &addr) < 0)
00510     goto fail;
00511 
00512   if (!length_obj)
00513     length = buf_len;
00514   else if (get_addr_from_python (length_obj, &length) < 0)
00515     goto fail;
00516 
00517   TRY_CATCH (except, RETURN_MASK_ALL)
00518     {
00519       write_memory_with_notification (addr, (gdb_byte *) buffer, length);
00520     }
00521 #ifdef IS_PY3K
00522   PyBuffer_Release (&pybuf);
00523 #endif
00524   GDB_PY_HANDLE_EXCEPTION (except);
00525 
00526   Py_RETURN_NONE;
00527 
00528  fail:
00529 #ifdef IS_PY3K
00530   PyBuffer_Release (&pybuf);
00531 #endif
00532   return NULL;
00533 }
00534 
00535 /* Destructor of Membuf objects.  */
00536 static void
00537 mbpy_dealloc (PyObject *self)
00538 {
00539   xfree (((membuf_object *) self)->buffer);
00540   Py_TYPE (self)->tp_free (self);
00541 }
00542 
00543 /* Return a description of the Membuf object.  */
00544 static PyObject *
00545 mbpy_str (PyObject *self)
00546 {
00547   membuf_object *membuf_obj = (membuf_object *) self;
00548 
00549   return PyString_FromFormat (_("Memory buffer for address %s, \
00550 which is %s bytes long."),
00551                               paddress (python_gdbarch, membuf_obj->addr),
00552                               pulongest (membuf_obj->length));
00553 }
00554 
00555 #ifdef IS_PY3K
00556 
00557 static int
00558 get_buffer (PyObject *self, Py_buffer *buf, int flags)
00559 {
00560   membuf_object *membuf_obj = (membuf_object *) self;
00561   int ret;
00562   
00563   ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
00564                            membuf_obj->length, 0, 
00565                            PyBUF_CONTIG);
00566   buf->format = "c";
00567 
00568   return ret;
00569 }
00570 
00571 #else
00572 
00573 static Py_ssize_t
00574 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
00575 {
00576   membuf_object *membuf_obj = (membuf_object *) self;
00577 
00578   if (segment)
00579     {
00580       PyErr_SetString (PyExc_SystemError,
00581                        _("The memory buffer supports only one segment."));
00582       return -1;
00583     }
00584 
00585   *ptrptr = membuf_obj->buffer;
00586 
00587   return membuf_obj->length;
00588 }
00589 
00590 static Py_ssize_t
00591 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
00592 {
00593   return get_read_buffer (self, segment, ptrptr);
00594 }
00595 
00596 static Py_ssize_t
00597 get_seg_count (PyObject *self, Py_ssize_t *lenp)
00598 {
00599   if (lenp)
00600     *lenp = ((membuf_object *) self)->length;
00601 
00602   return 1;
00603 }
00604 
00605 static Py_ssize_t
00606 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
00607 {
00608   void *ptr = NULL;
00609   Py_ssize_t ret;
00610 
00611   ret = get_read_buffer (self, segment, &ptr);
00612   *ptrptr = (char *) ptr;
00613 
00614   return ret;
00615 }
00616 
00617 #endif  /* IS_PY3K */
00618 
00619 /* Implementation of
00620    gdb.search_memory (address, length, pattern).  ADDRESS is the
00621    address to start the search.  LENGTH specifies the scope of the
00622    search from ADDRESS.  PATTERN is the pattern to search for (and
00623    must be a Python object supporting the buffer protocol).
00624    Returns a Python Long object holding the address where the pattern
00625    was located, or if the pattern was not found, returns None.  Returns NULL
00626    on error, with a python exception set.  */
00627 static PyObject *
00628 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
00629 {
00630   CORE_ADDR start_addr, length;
00631   static char *keywords[] = { "address", "length", "pattern", NULL };
00632   PyObject *start_addr_obj, *length_obj;
00633   volatile struct gdb_exception except;
00634   Py_ssize_t pattern_size;
00635   const void *buffer;
00636   CORE_ADDR found_addr;
00637   int found = 0;
00638 #ifdef IS_PY3K
00639   Py_buffer pybuf;
00640 
00641   if (! PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
00642                                      &start_addr_obj, &length_obj,
00643                                      &pybuf))
00644     return NULL;
00645 
00646   buffer = pybuf.buf;
00647   pattern_size = pybuf.len;
00648 #else
00649   PyObject *pattern;
00650   
00651   if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
00652                                      &start_addr_obj, &length_obj,
00653                                      &pattern))
00654      return NULL;
00655 
00656   if (!PyObject_CheckReadBuffer (pattern))
00657     {
00658       PyErr_SetString (PyExc_RuntimeError,
00659                        _("The pattern is not a Python buffer."));
00660 
00661       return NULL;
00662     }
00663 
00664   if (PyObject_AsReadBuffer (pattern, &buffer, &pattern_size) == -1)
00665     return NULL;
00666 #endif
00667 
00668   if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
00669     goto fail;
00670  
00671   if (get_addr_from_python (length_obj, &length) < 0)
00672     goto fail;
00673 
00674   if (!length)
00675     {
00676       PyErr_SetString (PyExc_ValueError,
00677                        _("Search range is empty."));
00678       goto fail;
00679     }
00680   /* Watch for overflows.  */
00681   else if (length > CORE_ADDR_MAX
00682            || (start_addr + length - 1) < start_addr)
00683     {
00684       PyErr_SetString (PyExc_ValueError,
00685                        _("The search range is too large."));
00686       goto fail;
00687     }
00688 
00689   TRY_CATCH (except, RETURN_MASK_ALL)
00690     {
00691       found = target_search_memory (start_addr, length,
00692                                     buffer, pattern_size,
00693                                     &found_addr);
00694     }
00695 #ifdef IS_PY3K
00696   PyBuffer_Release (&pybuf);
00697 #endif
00698   GDB_PY_HANDLE_EXCEPTION (except);
00699 
00700   if (found)
00701     return PyLong_FromLong (found_addr);
00702   else
00703     Py_RETURN_NONE;
00704 
00705  fail:
00706 #ifdef IS_PY3K
00707   PyBuffer_Release (&pybuf);
00708 #endif
00709   return NULL;
00710 }
00711 
00712 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
00713    Returns True if this inferior object still exists in GDB.  */
00714 
00715 static PyObject *
00716 infpy_is_valid (PyObject *self, PyObject *args)
00717 {
00718   inferior_object *inf = (inferior_object *) self;
00719 
00720   if (! inf->inferior)
00721     Py_RETURN_FALSE;
00722 
00723   Py_RETURN_TRUE;
00724 }
00725 
00726 static void
00727 infpy_dealloc (PyObject *obj)
00728 {
00729   inferior_object *inf_obj = (inferior_object *) obj;
00730   struct inferior *inf = inf_obj->inferior;
00731 
00732   if (! inf)
00733     return;
00734 
00735   set_inferior_data (inf, infpy_inf_data_key, NULL);
00736 }
00737 
00738 /* Clear the INFERIOR pointer in an Inferior object and clear the
00739    thread list.  */
00740 static void
00741 py_free_inferior (struct inferior *inf, void *datum)
00742 {
00743 
00744   struct cleanup *cleanup;
00745   inferior_object *inf_obj = datum;
00746   struct threadlist_entry *th_entry, *th_tmp;
00747 
00748   if (!gdb_python_initialized)
00749     return;
00750 
00751   cleanup = ensure_python_env (python_gdbarch, python_language);
00752 
00753   inf_obj->inferior = NULL;
00754 
00755   /* Deallocate threads list.  */
00756   for (th_entry = inf_obj->threads; th_entry != NULL;)
00757     {
00758       Py_DECREF (th_entry->thread_obj);
00759 
00760       th_tmp = th_entry;
00761       th_entry = th_entry->next;
00762       xfree (th_tmp);
00763     }
00764 
00765   inf_obj->nthreads = 0;
00766 
00767   Py_DECREF ((PyObject *) inf_obj);
00768   do_cleanups (cleanup);
00769 }
00770 
00771 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
00772    Returns the current inferior object.  */
00773 
00774 PyObject *
00775 gdbpy_selected_inferior (PyObject *self, PyObject *args)
00776 {
00777   return inferior_to_inferior_object (current_inferior ());
00778 }
00779 
00780 int
00781 gdbpy_initialize_inferior (void)
00782 {
00783   if (PyType_Ready (&inferior_object_type) < 0)
00784     return -1;
00785 
00786   if (gdb_pymodule_addobject (gdb_module, "Inferior",
00787                               (PyObject *) &inferior_object_type) < 0)
00788     return -1;
00789 
00790   infpy_inf_data_key =
00791     register_inferior_data_with_cleanup (NULL, py_free_inferior);
00792 
00793   observer_attach_new_thread (add_thread_object);
00794   observer_attach_thread_exit (delete_thread_object);
00795   observer_attach_normal_stop (python_on_normal_stop);
00796   observer_attach_target_resumed (python_on_resume);
00797   observer_attach_inferior_exit (python_inferior_exit);
00798   observer_attach_new_objfile (python_new_objfile);
00799 
00800   membuf_object_type.tp_new = PyType_GenericNew;
00801   if (PyType_Ready (&membuf_object_type) < 0)
00802     return -1;
00803 
00804   return gdb_pymodule_addobject (gdb_module, "Membuf", (PyObject *)
00805                                  &membuf_object_type);
00806 }
00807 
00808 static PyGetSetDef inferior_object_getset[] =
00809 {
00810   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
00811   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
00812     NULL },
00813   { "was_attached", infpy_get_was_attached, NULL,
00814     "True if the inferior was created using 'attach'.", NULL },
00815   { NULL }
00816 };
00817 
00818 static PyMethodDef inferior_object_methods[] =
00819 {
00820   { "is_valid", infpy_is_valid, METH_NOARGS,
00821     "is_valid () -> Boolean.\n\
00822 Return true if this inferior is valid, false if not." },
00823   { "threads", infpy_threads, METH_NOARGS,
00824     "Return all the threads of this inferior." },
00825   { "read_memory", (PyCFunction) infpy_read_memory,
00826     METH_VARARGS | METH_KEYWORDS,
00827     "read_memory (address, length) -> buffer\n\
00828 Return a buffer object for reading from the inferior's memory." },
00829   { "write_memory", (PyCFunction) infpy_write_memory,
00830     METH_VARARGS | METH_KEYWORDS,
00831     "write_memory (address, buffer [, length])\n\
00832 Write the given buffer object to the inferior's memory." },
00833   { "search_memory", (PyCFunction) infpy_search_memory,
00834     METH_VARARGS | METH_KEYWORDS,
00835     "search_memory (address, length, pattern) -> long\n\
00836 Return a long with the address of a match, or None." },
00837   { NULL }
00838 };
00839 
00840 static PyTypeObject inferior_object_type =
00841 {
00842   PyVarObject_HEAD_INIT (NULL, 0)
00843   "gdb.Inferior",                 /* tp_name */
00844   sizeof (inferior_object),       /* tp_basicsize */
00845   0,                              /* tp_itemsize */
00846   infpy_dealloc,                  /* tp_dealloc */
00847   0,                              /* tp_print */
00848   0,                              /* tp_getattr */
00849   0,                              /* tp_setattr */
00850   0,                              /* tp_compare */
00851   0,                              /* tp_repr */
00852   0,                              /* tp_as_number */
00853   0,                              /* tp_as_sequence */
00854   0,                              /* tp_as_mapping */
00855   0,                              /* tp_hash  */
00856   0,                              /* tp_call */
00857   0,                              /* tp_str */
00858   0,                              /* tp_getattro */
00859   0,                              /* tp_setattro */
00860   0,                              /* tp_as_buffer */
00861   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /* tp_flags */
00862   "GDB inferior object",          /* tp_doc */
00863   0,                              /* tp_traverse */
00864   0,                              /* tp_clear */
00865   0,                              /* tp_richcompare */
00866   0,                              /* tp_weaklistoffset */
00867   0,                              /* tp_iter */
00868   0,                              /* tp_iternext */
00869   inferior_object_methods,        /* tp_methods */
00870   0,                              /* tp_members */
00871   inferior_object_getset,         /* tp_getset */
00872   0,                              /* tp_base */
00873   0,                              /* tp_dict */
00874   0,                              /* tp_descr_get */
00875   0,                              /* tp_descr_set */
00876   0,                              /* tp_dictoffset */
00877   0,                              /* tp_init */
00878   0                               /* tp_alloc */
00879 };
00880 
00881 #ifdef IS_PY3K
00882 
00883 static PyBufferProcs buffer_procs =
00884 {
00885   get_buffer
00886 };
00887 
00888 #else
00889 
00890 /* Python doesn't provide a decent way to get compatibility here.  */
00891 #if HAVE_LIBPYTHON2_4
00892 #define CHARBUFFERPROC_NAME getcharbufferproc
00893 #else
00894 #define CHARBUFFERPROC_NAME charbufferproc
00895 #endif
00896 
00897 static PyBufferProcs buffer_procs = {
00898   get_read_buffer,
00899   get_write_buffer,
00900   get_seg_count,
00901   /* The cast here works around a difference between Python 2.4 and
00902      Python 2.5.  */
00903   (CHARBUFFERPROC_NAME) get_char_buffer
00904 };
00905 #endif  /* IS_PY3K */
00906 
00907 static PyTypeObject membuf_object_type = {
00908   PyVarObject_HEAD_INIT (NULL, 0)
00909   "gdb.Membuf",                   /*tp_name*/
00910   sizeof (membuf_object),         /*tp_basicsize*/
00911   0,                              /*tp_itemsize*/
00912   mbpy_dealloc,                   /*tp_dealloc*/
00913   0,                              /*tp_print*/
00914   0,                              /*tp_getattr*/
00915   0,                              /*tp_setattr*/
00916   0,                              /*tp_compare*/
00917   0,                              /*tp_repr*/
00918   0,                              /*tp_as_number*/
00919   0,                              /*tp_as_sequence*/
00920   0,                              /*tp_as_mapping*/
00921   0,                              /*tp_hash */
00922   0,                              /*tp_call*/
00923   mbpy_str,                       /*tp_str*/
00924   0,                              /*tp_getattro*/
00925   0,                              /*tp_setattro*/
00926   &buffer_procs,                  /*tp_as_buffer*/
00927   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
00928   "GDB memory buffer object",     /*tp_doc*/
00929   0,                              /* tp_traverse */
00930   0,                              /* tp_clear */
00931   0,                              /* tp_richcompare */
00932   0,                              /* tp_weaklistoffset */
00933   0,                              /* tp_iter */
00934   0,                              /* tp_iternext */
00935   0,                              /* tp_methods */
00936   0,                              /* tp_members */
00937   0,                              /* tp_getset */
00938   0,                              /* tp_base */
00939   0,                              /* tp_dict */
00940   0,                              /* tp_descr_get */
00941   0,                              /* tp_descr_set */
00942   0,                              /* tp_dictoffset */
00943   0,                              /* tp_init */
00944   0,                              /* tp_alloc */
00945 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines