1 diff -ruN Python-2.6.7-orig/Makefile.pre.in Python-2.6.7/Makefile.pre.in
   2 --- Python-2.6.7-orig/Makefile.pre.in   2010-08-01 22:05:31.000000000 +0000
   3 +++ Python-2.6.7/Makefile.pre.in        2012-02-16 03:15:25.704717695 +0000
   4 @@ -352,7 +352,7 @@
   5  
   6  # Default target
   7  all:           build_all
   8 -build_all:     $(BUILDPYTHON) oldsharedmods sharedmods
   9 +build_all:     $(BUILDPYTHON) oldsharedmods sharedmods build-py_db
  10  
  11  # Compile a binary with gcc profile guided optimization.
  12  profile-opt:
  13 @@ -663,6 +663,19 @@
  14  
  15  $(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
  16  
  17 +SHLIB_FLAGS = -shared -fpic -Wl,-M,$(srcdir)/py_db/mapfile-vers
  18 +
  19 +libpython2.6_db.so.1.0:        $(srcdir)/py_db/libpython26_db.c
  20 +       $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) $(SHLIB_FLAGS) $<
  21 +
  22 +check_offset:  $(srcdir)/py_db/check_offsets.c
  23 +       $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) $<
  24 +
  25 +build-py_db:   libpython2.6_db.so.1.0 check_offset
  26 +
  27 +install-py_db: libpython2.6_db.so.1.0 check_offset
  28 +       $(INSTALL_SHARED) libpython2.6_db.so.1.0 $(DESTDIR)$(LIBDIR)
  29 +       $(INSTALL_PROGRAM) check_offset $(DESTDIR)$(BINDIR)
  30  
  31  ######################################################################
  32  
  33 @@ -726,7 +739,7 @@
  34                 $(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
  35  
  36  # Install everything
  37 -install:       @FRAMEWORKINSTALLFIRST@ altinstall bininstall maninstall @FRAMEWORKINSTALLLAST@
  38 +install:       @FRAMEWORKINSTALLFIRST@ altinstall bininstall maninstall @FRAMEWORKINSTALLLAST@ install-py_db
  39  
  40  # Install almost everything without disturbing previous versions
  41  altinstall:    @FRAMEWORKALTINSTALLFIRST@ altbininstall libinstall inclinstall libainstall \
  42 diff -ruN Python-2.6.7-orig/py_db/check_offsets.c Python-2.6.7/py_db/check_offsets.c
  43 --- Python-2.6.7-orig/py_db/check_offsets.c     1970-01-01 00:00:00.000000000 +0000
  44 +++ Python-2.6.7/py_db/check_offsets.c  2012-02-16 03:13:33.350841679 +0000
  45 @@ -0,0 +1,88 @@
  46 +/*
  47 + * CDDL HEADER START
  48 + *
  49 + * The contents of this file are subject to the terms of the
  50 + * Common Development and Distribution License (the "License").
  51 + * You may not use this file except in compliance with the License.
  52 + *
  53 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  54 + * or http://www.opensolaris.org/os/licensing.
  55 + * See the License for the specific language governing permissions
  56 + * and limitations under the License.
  57 + *
  58 + * When distributing Covered Code, include this CDDL HEADER in each
  59 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  60 + * If applicable, add the following below this CDDL HEADER, with the
  61 + * fields enclosed by brackets "[]" replaced with your own identifying
  62 + * information: Portions Copyright [yyyy] [name of copyright owner]
  63 + *
  64 + * CDDL HEADER END
  65 + */
  66 +/*
  67 + * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  68 + * Use is subject to license terms.
  69 + */
  70 +
  71 +#include <stdio.h>
  72 +
  73 +#include <Python.h>
  74 +#include <frameobject.h>
  75 +
  76 +#include "libpython26_db_32.h"
  77 +
  78 +#if 0
  79 +#define        offsetof(s, m)  ((size_t)(&(((s *)0)->m)))
  80 +#endif
  81 +
  82 +int
  83 +main(void)
  84 +{
  85 +/*
  86 + * PyCodeObject co_name
  87 + * PyCodeObject co_filename
  88 + * PyCodeObject co_lnotab
  89 + * PyFrameObject f_back
  90 + * PyFrameObject f_code
  91 + * PyFrameObject f_lasti
  92 + * PyInterpreterState next
  93 + * PyInterpreterState tstate_head
  94 + * PyStringObject ob_sval
  95 + * PyStringObject ob_size
  96 + * PyThreadState frame
  97 + * PyThreadState next
  98 + */
  99 +
 100 +       printf("struct member: native 32\n");
 101 +       printf("PyCodeObject co_name: %d %d\n", offsetof(PyCodeObject, co_name),
 102 +           offsetof(PyCodeObject32, co_name));
 103 +       printf("PyCodeObject co_filename: %d %d\n", offsetof(PyCodeObject,
 104 +           co_filename), offsetof(PyCodeObject32, co_filename));
 105 +       printf("PyCodeObject co_lnotab: %d %d\n", offsetof(PyCodeObject,
 106 +           co_lnotab), offsetof(PyCodeObject32, co_lnotab));
 107 +       printf("PyFrameObject f_back: %d %d\n", offsetof(PyFrameObject, f_back),
 108 +           offsetof(PyFrameObject32, f_back));
 109 +       printf("PyFrameObject f_code: %d %d\n", offsetof(PyFrameObject, f_code),
 110 +           offsetof(PyFrameObject32, f_code));
 111 +       printf("PyFrameObject f_lasti: %d %d\n", offsetof(PyFrameObject,
 112 +           f_lasti), offsetof(PyFrameObject32, f_lasti));
 113 +       printf("PyInterpreterState next: %d %d\n", offsetof(PyInterpreterState,
 114 +           next), offsetof(PyInterpreterState32, next));
 115 +       printf("PyInterpreterState tstate_head: %d %d\n",
 116 +           offsetof(PyInterpreterState, tstate_head),
 117 +           offsetof(PyInterpreterState32, tstate_head));
 118 +       printf("PyStringObject ob_sval: %d %d\n", offsetof(PyStringObject,
 119 +           ob_sval), offsetof(PyStringObject32, ob_sval));
 120 +       printf("PyStringObject ob_size: %d %d\n", offsetof(PyStringObject,
 121 +           ob_size), offsetof(PyStringObject32, ob_size));
 122 +       printf("PyThreadState frame: %d %d\n", offsetof(PyThreadState, frame),
 123 +           offsetof(PyThreadState32, frame));
 124 +       printf("PyThreadState next: %d %d\n", offsetof(PyThreadState, next),
 125 +           offsetof(PyThreadState32, next));
 126 +
 127 +       printf("\nObject sizes\n");
 128 +       printf("PyObject: %d %d\n", sizeof (PyObject), sizeof (PyObject32));
 129 +       printf("PyVarObject: %d %d\n", sizeof (PyVarObject),
 130 +           sizeof (PyVarObject32));
 131 +
 132 +       return (0);
 133 +}
 134 diff -ruN Python-2.6.7-orig/py_db/libpython26_db_32.h Python-2.6.7/py_db/libpython26_db_32.h
 135 --- Python-2.6.7-orig/py_db/libpython26_db_32.h 1970-01-01 00:00:00.000000000 +0000
 136 +++ Python-2.6.7/py_db/libpython26_db_32.h      2012-02-16 03:13:33.351452724 +0000
 137 @@ -0,0 +1,122 @@
 138 +/*
 139 + * CDDL HEADER START
 140 + *
 141 + * The contents of this file are subject to the terms of the
 142 + * Common Development and Distribution License (the "License").
 143 + * You may not use this file except in compliance with the License.
 144 + *
 145 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 146 + * or http://www.opensolaris.org/os/licensing.
 147 + * See the License for the specific language governing permissions
 148 + * and limitations under the License.
 149 + *
 150 + * When distributing Covered Code, include this CDDL HEADER in each
 151 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 152 + * If applicable, add the following below this CDDL HEADER, with the
 153 + * fields enclosed by brackets "[]" replaced with your own identifying
 154 + * information: Portions Copyright [yyyy] [name of copyright owner]
 155 + *
 156 + * CDDL HEADER END
 157 + */
 158 +/*
 159 + * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 160 + * Use is subject to license terms.
 161 + */
 162 +
 163 +#ifndef        _LIBPYTHON26_DB_32_H
 164 +#define        _LIBPYTHON26_DB_32_H
 165 +
 166 +#ifdef __cplusplus
 167 +extern "C" {
 168 +#endif
 169 +
 170 +#include <sys/types.h>
 171 +
 172 +/*
 173 + * Define 32-bit Python data structures for use by the 64-bit debugger.  This
 174 + * is so that a 64-bit debugger may properly examine a 32-bit process.
 175 + *
 176 + * In many cases, the debug library is only concerned with a few fields in the
 177 + * Python structure.  In that case, the other ancillary fields are elided.
 178 + */
 179 +
 180 +typedef uint32_t uintptr32_t;
 181 +typedef int32_t Py_ssize32_t;
 182 +
 183 +typedef struct _is32 {
 184 +       uintptr32_t     next;
 185 +       uintptr32_t     tstate_head;
 186 +} PyInterpreterState32;
 187 +
 188 +typedef struct _ts32 {
 189 +       uintptr32_t     next;
 190 +       uintptr32_t     interp;
 191 +       uintptr32_t     frame;
 192 +} PyThreadState32;
 193 +
 194 +#define        PyObject_HEAD32                 \
 195 +       Py_ssize32_t    ob_refcnt;      \
 196 +       uintptr32_t     ob_type;
 197 +
 198 +#define        PyObject_VAR_HEAD32             \
 199 +       PyObject_HEAD32                 \
 200 +       Py_ssize32_t    ob_size;
 201 +
 202 +typedef struct {
 203 +       PyObject_HEAD32
 204 +} PyObject32;
 205 +
 206 +typedef struct {
 207 +       PyObject_VAR_HEAD32
 208 +} PyVarObject32;
 209 +
 210 +typedef struct {
 211 +       PyObject_VAR_HEAD32
 212 +       int32_t         ob_shash;
 213 +       int             ob_sstate;
 214 +       char            ob_sval[1];
 215 +} PyStringObject32;
 216 +
 217 +#define        Py_SIZE32(ob)                   (((PyVarObject32*)(ob))->ob_size)
 218 +#define        PyString_GET_SIZE32(op)         Py_SIZE32(op)
 219 +#define        PyString_AS_STRING32(op)        (((PyStringObject32 *)(op))->ob_sval)
 220 +
 221 +typedef struct {
 222 +       PyObject_VAR_HEAD32
 223 +       uintptr32_t     f_back;
 224 +       uintptr32_t     f_code;
 225 +       uintptr32_t     f_builtins;
 226 +       uintptr32_t     f_globals;
 227 +       uintptr32_t     f_locals;
 228 +       uintptr32_t     f_valuestack;
 229 +       uintptr32_t     f_stacktop;
 230 +       uintptr32_t     f_trace;
 231 +       uintptr32_t     f_exc_typpe, f_exc_value, f_exc_traceback;
 232 +       uintptr32_t     f_tstate;
 233 +       int             f_lasti;
 234 +       int             f_lineno;
 235 +} PyFrameObject32;
 236 +
 237 +typedef struct {
 238 +       PyObject_HEAD32
 239 +       int             co_argcount;
 240 +       int             co_nlocals;
 241 +       int             co_stacksize;
 242 +       int             co_flags;
 243 +       uintptr32_t     co_code;
 244 +       uintptr32_t     co_consts;
 245 +       uintptr32_t     co_names;
 246 +       uintptr32_t     co_varnames;
 247 +       uintptr32_t     co_freevars;
 248 +       uintptr32_t     co_cellvars;
 249 +       uintptr32_t     co_filename;
 250 +       uintptr32_t     co_name;
 251 +       int             co_firstlineno;
 252 +       uintptr32_t     co_lnotab;
 253 +} PyCodeObject32;
 254 +
 255 +#ifdef __cplusplus
 256 +}
 257 +#endif
 258 +
 259 +#endif /* _LIBPYTHON26_DB_32_H */
 260 diff -ruN Python-2.6.7-orig/py_db/libpython26_db.c Python-2.6.7/py_db/libpython26_db.c
 261 --- Python-2.6.7-orig/py_db/libpython26_db.c    1970-01-01 00:00:00.000000000 +0000
 262 +++ Python-2.6.7/py_db/libpython26_db.c 2012-02-16 03:13:33.351199719 +0000
 263 @@ -0,0 +1,655 @@
 264 +/*
 265 + * CDDL HEADER START
 266 + *
 267 + * The contents of this file are subject to the terms of the
 268 + * Common Development and Distribution License (the "License").
 269 + * You may not use this file except in compliance with the License.
 270 + *
 271 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 272 + * or http://www.opensolaris.org/os/licensing.
 273 + * See the License for the specific language governing permissions
 274 + * and limitations under the License.
 275 + *
 276 + * When distributing Covered Code, include this CDDL HEADER in each
 277 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 278 + * If applicable, add the following below this CDDL HEADER, with the
 279 + * fields enclosed by brackets "[]" replaced with your own identifying
 280 + * information: Portions Copyright [yyyy] [name of copyright owner]
 281 + *
 282 + * CDDL HEADER END
 283 + */
 284 +/*
 285 + * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 286 + * Use is subject to license terms.
 287 + */
 288 +
 289 +#include <stdio.h>
 290 +#include <stdlib.h>
 291 +#include <string.h>
 292 +#include <errno.h>
 293 +#include <gelf.h>
 294 +
 295 +#include <Python.h>
 296 +#include <frameobject.h>
 297 +
 298 +#include "libpython26_db.h"
 299 +#if defined(_LP64)
 300 +#include "libpython26_db_32.h"
 301 +#endif /* _LP64 */
 302 +
 303 +/*
 304 + * Because MDB always runs the debugger in the same datamodel as the target,
 305 + * only functions that are used by the procfs part of this interface (or shared
 306 + * between the two) are written as 64->32 aware.
 307 + */
 308 +typedef struct pydb_arch_ops {
 309 +       ssize_t (*strobj_readdata)(pydb_agent_t *, uintptr_t, unsigned char *,
 310 +           size_t);
 311 +       int     (*frameinfo)(pydb_agent_t *, uintptr_t, char *,
 312 +           size_t, char *, size_t, int *);
 313 +} pydb_arch_ops_t;
 314 +
 315 +struct pydb_agent {
 316 +       struct ps_prochandle *pdb_ph;
 317 +       int pdb_vers;
 318 +       int pdb_is_64bit;
 319 +       int pdb_datamodel;
 320 +       const pydb_arch_ops_t *pdb_ops;
 321 +};
 322 +
 323 +typedef uintptr_t (*pdi_next_cb_t)(pydb_iter_t *);
 324 +
 325 +struct pydb_iter {
 326 +       struct ps_prochandle *pdi_ph;
 327 +       uintptr_t pdi_current;
 328 +       pdi_next_cb_t pdi_nextf;
 329 +};
 330 +
 331 +#define        LIBPYTHON       "libpython2.6.so"
 332 +
 333 +#define        MIN(x, y)       (((x) < (y)) ? (x) : (y))
 334 +
 335 +/* Generic interface to helper functions */
 336 +static ssize_t pydb_strobj_readdata(pydb_agent_t *py, uintptr_t addr,
 337 +    unsigned char *buf, size_t buf_len);
 338 +static int pydb_getlno(pydb_agent_t *py, uintptr_t lnotab_addr, int firstline,
 339 +    int lastinst);
 340 +static int pydb_frameinfo(pydb_agent_t *py, uintptr_t addr, char *funcnm,
 341 +    size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
 342 +
 343 +/* datamodel specific implementation of helper functions */
 344 +static ssize_t pydb_strobj_readdata_native(pydb_agent_t *py, uintptr_t addr,
 345 +    unsigned char *buf, size_t buf_len);
 346 +static int pydb_frameinfo_native(pydb_agent_t *py, uintptr_t addr, char *funcnm,
 347 +    size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
 348 +
 349 +#if defined (_LP64)
 350 +static ssize_t pydb_strobj_readdata_32(pydb_agent_t *py, uintptr_t addr,
 351 +    unsigned char *buf, size_t buf_len);
 352 +static int pydb_frameinfo_32(pydb_agent_t *py, uintptr_t addr, char *funcnm,
 353 +    size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
 354 +#endif /* _LP64 */
 355 +
 356 +static ssize_t pydb_strobj_readstr(pydb_agent_t *py, uintptr_t addr, char *buf,
 357 +    size_t len);
 358 +
 359 +/* Iterator function next routines.  Plugable, configured by iterator init */
 360 +static uintptr_t pydb_frame_iter_next(pydb_iter_t *iter);
 361 +static uintptr_t pydb_interp_iter_next(pydb_iter_t *iter);
 362 +static uintptr_t pydb_thread_iter_next(pydb_iter_t *iter);
 363 +
 364 +static const char *strbasename(const char *s);
 365 +
 366 +static const pydb_arch_ops_t arch_ops_native = {
 367 +       .frameinfo = pydb_frameinfo_native,
 368 +       .strobj_readdata = pydb_strobj_readdata_native,
 369 +};
 370 +
 371 +#if defined (_LP64)
 372 +static const pydb_arch_ops_t arch_ops_32 = {
 373 +       .frameinfo = pydb_frameinfo_32,
 374 +       .strobj_readdata = pydb_strobj_readdata_32,
 375 +};
 376 +#endif /* _LP64 */
 377 +
 378 +static const char *
 379 +strbasename(const char *s)
 380 +{
 381 +       const char *p = strrchr(s, '/');
 382 +
 383 +       if (p == NULL)
 384 +               return (s);
 385 +
 386 +       return (++p);
 387 +}
 388 +
 389 +/* Agent creation / destruction routines */
 390 +
 391 +pydb_agent_t *
 392 +pydb_agent_create(struct ps_prochandle *P, int vers)
 393 +{
 394 +       pydb_agent_t *py;
 395 +       int datamodel;
 396 +
 397 +       if (vers != PYDB_VERSION) {
 398 +               errno = ENOTSUP;
 399 +               return (NULL);
 400 +       }
 401 +
 402 +       if (ps_pdmodel(P, &datamodel) != PS_OK) {
 403 +               return (NULL);
 404 +       }
 405 +
 406 +       py = (pydb_agent_t *)malloc(sizeof (pydb_agent_t));
 407 +       if (py == NULL) {
 408 +               return (NULL);
 409 +       }
 410 +
 411 +       py->pdb_ph = P;
 412 +       py->pdb_vers = vers;
 413 +       py->pdb_datamodel = datamodel;
 414 +       py->pdb_is_64bit = 0;
 415 +       py->pdb_ops = &arch_ops_native;
 416 +
 417 +#if defined (_LP64)
 418 +       py->pdb_is_64bit = (datamodel == PR_MODEL_LP64);
 419 +       if (!py->pdb_is_64bit) {
 420 +               py->pdb_ops = &arch_ops_32;
 421 +       }
 422 +#endif /* _LP64 */
 423 +
 424 +       return (py);
 425 +}
 426 +
 427 +void
 428 +pydb_agent_destroy(pydb_agent_t *py)
 429 +{
 430 +       if (py == NULL) {
 431 +               return;
 432 +       }
 433 +
 434 +       free(py);
 435 +}
 436 +
 437 +/* Helper functions */
 438 +static int
 439 +pydb_getlno(pydb_agent_t *py, uintptr_t lnotab_addr, int firstline,
 440 +    int lastinst)
 441 +{
 442 +       unsigned char lnotab[4096];
 443 +       ssize_t lnotab_len;
 444 +       int addr, line;
 445 +       int i;
 446 +
 447 +       lnotab_len = pydb_strobj_readdata(py, lnotab_addr, lnotab,
 448 +           sizeof (lnotab));
 449 +       if (lnotab_len < 0) {
 450 +               return (-1);
 451 +       }
 452 +
 453 +       /*
 454 +        * Python's line number algorithm is arcane. See here for details:
 455 +        * http://svn.python.org/projects/python/trunk/Objects/lnotab_notes.txt
 456 +        */
 457 +
 458 +       line = firstline;
 459 +       for (addr = i = 0; i < lnotab_len; i += 2) {
 460 +               if (addr + lnotab[i] > lastinst) {
 461 +                       break;
 462 +               }
 463 +               addr += lnotab[i];
 464 +               line += lnotab[i + 1];
 465 +       }
 466 +
 467 +       return (line);
 468 +}
 469 +
 470 +static ssize_t
 471 +pydb_strobj_readdata(pydb_agent_t *py, uintptr_t addr, unsigned char *buf,
 472 +    size_t buf_len)
 473 +{
 474 +       return (py->pdb_ops->strobj_readdata(py, addr, buf, buf_len));
 475 +}
 476 +
 477 +static ssize_t
 478 +pydb_strobj_readdata_native(pydb_agent_t *py, uintptr_t addr,
 479 +    unsigned char *buf, size_t buf_len)
 480 +{
 481 +       PyStringObject sobj;
 482 +       ssize_t obj_sz;
 483 +       ssize_t read_sz;
 484 +       psaddr_t straddr;
 485 +
 486 +       /*
 487 +        * PyStringObjects are variable size.  The size of the PyStringObject
 488 +        * struct is fixed, and known at compile time; however, the size of the
 489 +        * associated buffer is variable.  The char[1] element at the end of the
 490 +        * structure contains the string, and the ob_size of the PyStringObject
 491 +        * indicates how much extra space was allocated to contain the string
 492 +        * buffer at the object's tail.  Read in the fixed size portion of the
 493 +        * object first, and then read the contents of the data buffer into the
 494 +        * buffer passed by the caller.
 495 +        */
 496 +
 497 +       if (ps_pread(py->pdb_ph, addr, &sobj, sizeof (PyStringObject))
 498 +           != PS_OK) {
 499 +               return (-1);
 500 +       }
 501 +
 502 +       obj_sz = (ssize_t)PyString_GET_SIZE(&sobj);
 503 +
 504 +       read_sz = MIN(obj_sz, (ssize_t)buf_len);
 505 +       straddr = (psaddr_t)(addr + offsetof(PyStringObject, ob_sval));
 506 +
 507 +       if (ps_pread(py->pdb_ph, straddr, buf, (size_t)read_sz) != PS_OK) {
 508 +               return (-1);
 509 +       }
 510 +
 511 +       return (read_sz);
 512 +}
 513 +
 514 +#if defined(_LP64)
 515 +static ssize_t
 516 +pydb_strobj_readdata_32(pydb_agent_t *py, uintptr_t addr,
 517 +    unsigned char *buf, size_t buf_len)
 518 +{
 519 +       PyStringObject32 sobj;
 520 +       ssize_t obj_sz;
 521 +       ssize_t read_sz;
 522 +       psaddr_t straddr;
 523 +
 524 +       /*
 525 +        * PyStringObjects are variable size.  The size of the PyStringObject
 526 +        * struct is fixed, and known at compile time; however, the size of the
 527 +        * associated buffer is variable.  The char[1] element at the end of the
 528 +        * structure contains the string, and the ob_size of the PyStringObject
 529 +        * indicates how much extra space was allocated to contain the string
 530 +        * buffer at the object's tail.  Read in the fixed size portion of the
 531 +        * object first, and then read the contents of the data buffer into the
 532 +        * buffer passed by the caller.
 533 +        */
 534 +
 535 +       if (ps_pread(py->pdb_ph, addr, &sobj, sizeof (PyStringObject32))
 536 +           != PS_OK) {
 537 +               return (-1);
 538 +       }
 539 +
 540 +       obj_sz = (ssize_t)PyString_GET_SIZE32(&sobj);
 541 +
 542 +       read_sz = MIN(obj_sz, (ssize_t)buf_len);
 543 +       straddr = (psaddr_t)(addr + offsetof(PyStringObject32, ob_sval));
 544 +
 545 +       if (ps_pread(py->pdb_ph, straddr, buf, (size_t)read_sz) != PS_OK) {
 546 +               return (-1);
 547 +       }
 548 +
 549 +       return (read_sz);
 550 +}
 551 +#endif /* _LP64 */
 552 +
 553 +/*
 554 + * Most Python PyStringObjects contain strings, as one would expect.  However,
 555 + * due to some sleazy hackery in parts of the Python code, some string objects
 556 + * are used as buffers for binary data.  In the general case,
 557 + * pydb_strobj_readstr() should be used to read strings out of string objects.
 558 + * It wraps pydb_strobj_readdata(), which should be used by callers only when
 559 + * trying to retrieve binary data.  (This routine does some string cleanup).
 560 + */
 561 +static ssize_t
 562 +pydb_strobj_readstr(pydb_agent_t *py, uintptr_t addr, char *buf,
 563 +    size_t buf_len)
 564 +{
 565 +       ssize_t read_sz;
 566 +
 567 +       read_sz = pydb_strobj_readdata(py, addr, (unsigned char *)buf, buf_len);
 568 +
 569 +       if (read_sz >= 0) {
 570 +               if (read_sz >= buf_len) {
 571 +                       read_sz = buf_len - 1;
 572 +               }
 573 +
 574 +               buf[read_sz] = '\0';
 575 +       }
 576 +
 577 +       return (read_sz);
 578 +}
 579 +
 580 +
 581 +static int
 582 +pydb_frameinfo(pydb_agent_t *py, uintptr_t addr, char *funcnm,
 583 +    size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno)
 584 +{
 585 +       return (py->pdb_ops->frameinfo(py, addr, funcnm, funcnm_sz,
 586 +           filenm, filenm_sz, lineno));
 587 +}
 588 +
 589 +static int
 590 +pydb_frameinfo_native(pydb_agent_t *py, uintptr_t addr, char *funcnm,
 591 +    size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno)
 592 +{
 593 +       PyFrameObject fo;
 594 +       PyCodeObject co;
 595 +       ssize_t rc;
 596 +
 597 +       if (ps_pread(py->pdb_ph, addr, &fo, sizeof (PyFrameObject))
 598 +           != PS_OK) {
 599 +               return (-1);
 600 +       }
 601 +
 602 +       if (ps_pread(py->pdb_ph, (uintptr_t)fo.f_code, &co,
 603 +           sizeof (PyCodeObject)) != PS_OK) {
 604 +               return (-1);
 605 +       }
 606 +
 607 +       rc = pydb_strobj_readstr(py, (uintptr_t)co.co_name, funcnm, funcnm_sz);
 608 +       if (rc < 0) {
 609 +               return (-1);
 610 +       }
 611 +
 612 +       rc = pydb_strobj_readstr(py, (uintptr_t)co.co_filename, filenm,
 613 +           filenm_sz);
 614 +       if (rc < 0) {
 615 +               return (-1);
 616 +       }
 617 +
 618 +       *lineno = pydb_getlno(py, (uintptr_t)co.co_lnotab, co.co_firstlineno,
 619 +           fo.f_lasti);
 620 +       if (*lineno < 0) {
 621 +               return (-1);
 622 +       }
 623 +
 624 +       return (0);
 625 +}
 626 +
 627 +#if defined (_LP64)
 628 +static int
 629 +pydb_frameinfo_32(pydb_agent_t *py, uintptr_t addr, char *funcnm,
 630 +    size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno)
 631 +{
 632 +       PyFrameObject32 fo;
 633 +       PyCodeObject32 co;
 634 +       ssize_t rc;
 635 +
 636 +       if (ps_pread(py->pdb_ph, addr, &fo, sizeof (PyFrameObject32))
 637 +           != PS_OK) {
 638 +               return (-1);
 639 +       }
 640 +
 641 +       if (ps_pread(py->pdb_ph, (uintptr_t)fo.f_code, &co,
 642 +           sizeof (PyCodeObject32)) != PS_OK) {
 643 +               return (-1);
 644 +       }
 645 +
 646 +       rc = pydb_strobj_readstr(py, (uintptr_t)co.co_name, funcnm, funcnm_sz);
 647 +       if (rc < 0) {
 648 +               return (-1);
 649 +       }
 650 +
 651 +       rc = pydb_strobj_readstr(py, (uintptr_t)co.co_filename, filenm,
 652 +           filenm_sz);
 653 +       if (rc < 0) {
 654 +               return (-1);
 655 +       }
 656 +
 657 +       *lineno = pydb_getlno(py, (uintptr_t)co.co_lnotab, co.co_firstlineno,
 658 +           fo.f_lasti);
 659 +       if (*lineno < 0) {
 660 +               return (-1);
 661 +       }
 662 +
 663 +       return (0);
 664 +}
 665 +
 666 +#endif /* _LP64 */
 667 +
 668 +/* Functions that are part of the library's interface */
 669 +
 670 +/*
 671 + * Given the address of a PyFrameObject, and a buffer of a known size,
 672 + * fill the buffer with a description of the frame.
 673 + */
 674 +int
 675 +pydb_get_frameinfo(pydb_agent_t *py, uintptr_t frame_addr, char *fbuf,
 676 +    size_t bufsz, int verbose)
 677 +{
 678 +       char funcname[1024];
 679 +       char filename[1024];
 680 +       char *fn;
 681 +       int lineno;
 682 +       int length = (py->pdb_is_64bit ? 16 : 8);
 683 +       int rc;
 684 +
 685 +       rc = pydb_frameinfo(py, frame_addr, funcname, sizeof (funcname),
 686 +           filename, sizeof (filename), &lineno);
 687 +       if (rc < 0) {
 688 +               return (-1);
 689 +       }
 690 +
 691 +       if (!verbose) {
 692 +               fn = (char *)strbasename(filename);
 693 +       } else {
 694 +               fn = filename;
 695 +       }
 696 +
 697 +       (void) snprintf(fbuf, bufsz, "%0.*lx %s:%d %s()\n", length,
 698 +           frame_addr, fn, lineno, funcname);
 699 +
 700 +       return (0);
 701 +}
 702 +
 703 +/*
 704 + * Return a description about a PyFrameObject, if the object is
 705 + * actually a PyFrameObject.  In this case, the pc argument is checked
 706 + * to make sure that it came from a function that takes a PyFrameObject
 707 + * as its first (argv[0]) argument.
 708 + */
 709 +int
 710 +pydb_pc_frameinfo(pydb_agent_t *py, uintptr_t pc, uintptr_t frame_addr,
 711 +    char *fbuf, size_t bufsz)
 712 +{
 713 +       char funcname[1024];
 714 +       char filename[1024];
 715 +       int lineno;
 716 +       int rc;
 717 +       ps_sym_t psym;
 718 +
 719 +       /*
 720 +        * If PC doesn't match PyEval_EvalFrameEx in either libpython
 721 +        * or the executable, don't decode it.
 722 +        */
 723 +       if (ps_pglobal_sym(py->pdb_ph, LIBPYTHON, "PyEval_EvalFrameEx", &psym)
 724 +           != PS_OK) {
 725 +               return (-1);
 726 +       }
 727 +
 728 +       /* If symbol found, ensure that PC falls within PyEval_EvalFrameEx. */
 729 +       if (pc < psym.st_value || pc > psym.st_value + psym.st_size) {
 730 +               return (-1);
 731 +       }
 732 +
 733 +       rc = pydb_frameinfo(py, frame_addr, funcname, sizeof (funcname),
 734 +           filename, sizeof (filename), &lineno);
 735 +       if (rc < 0) {
 736 +               return (-1);
 737 +       }
 738 +
 739 +       (void) snprintf(fbuf, bufsz, "[ %s:%d (%s) ]\n", filename, lineno,
 740 +           funcname);
 741 +
 742 +       return (0);
 743 +}
 744 +
 745 +/*
 746 + * Walks the list of PyInterpreterState objects.  If caller doesn't
 747 + * supply address of list, this method will look it up.
 748 + */
 749 +pydb_iter_t *
 750 +pydb_interp_iter_init(pydb_agent_t *py, uintptr_t addr)
 751 +{
 752 +       pydb_iter_t *itr;
 753 +       uintptr_t i_addr;
 754 +       int rc;
 755 +
 756 +       if (addr == 0) {
 757 +               rc = ps_pglobal_lookup(py->pdb_ph, LIBPYTHON, "interp_head",
 758 +                   (psaddr_t *)&addr);
 759 +               if (rc != PS_OK) {
 760 +                       return (NULL);
 761 +               }
 762 +       }
 763 +
 764 +       if (ps_pread(py->pdb_ph, (uintptr_t)addr, &i_addr, sizeof (uintptr_t))
 765 +           != PS_OK) {
 766 +               return (NULL);
 767 +       }
 768 +
 769 +       itr = malloc(sizeof (pydb_iter_t));
 770 +       if (itr == NULL) {
 771 +               return (NULL);
 772 +       }
 773 +
 774 +       itr->pdi_ph = py->pdb_ph;
 775 +       itr->pdi_current = i_addr;
 776 +       itr->pdi_nextf = pydb_interp_iter_next;
 777 +
 778 +       return (itr);
 779 +}
 780 +
 781 +static uintptr_t
 782 +pydb_interp_iter_next(pydb_iter_t *iter)
 783 +{
 784 +       PyInterpreterState st;
 785 +       uintptr_t cur;
 786 +
 787 +       cur = iter->pdi_current;
 788 +
 789 +       if (cur == 0) {
 790 +               return (cur);
 791 +       }
 792 +
 793 +       if (ps_pread(iter->pdi_ph, cur, &st, sizeof (PyInterpreterState))
 794 +           != PS_OK) {
 795 +               iter->pdi_current = 0;
 796 +               return (0);
 797 +       }
 798 +
 799 +       iter->pdi_current = (uintptr_t)st.next;
 800 +
 801 +       return (cur);
 802 +}
 803 +
 804 +/*
 805 + * Walk a list of Python PyFrameObjects.  The addr argument must be
 806 + * the address of a valid PyThreadState object.
 807 + */
 808 +pydb_iter_t *
 809 +pydb_frame_iter_init(pydb_agent_t *py, uintptr_t addr)
 810 +{
 811 +       pydb_iter_t *itr;
 812 +       PyThreadState ts;
 813 +
 814 +       if (ps_pread(py->pdb_ph, (uintptr_t)addr, &ts, sizeof (PyThreadState))
 815 +           != PS_OK) {
 816 +               return (NULL);
 817 +       }
 818 +
 819 +       itr = malloc(sizeof (pydb_iter_t));
 820 +       if (itr == NULL) {
 821 +               return (NULL);
 822 +       }
 823 +
 824 +       itr->pdi_ph = py->pdb_ph;
 825 +       itr->pdi_current = (uintptr_t)ts.frame;
 826 +       itr->pdi_nextf = pydb_frame_iter_next;
 827 +
 828 +       return (itr);
 829 +}
 830 +
 831 +static uintptr_t
 832 +pydb_frame_iter_next(pydb_iter_t *iter)
 833 +{
 834 +       PyFrameObject fo;
 835 +       uintptr_t cur;
 836 +
 837 +       cur = iter->pdi_current;
 838 +
 839 +       if (cur == 0) {
 840 +               return (cur);
 841 +       }
 842 +
 843 +       if (ps_pread(iter->pdi_ph, cur, &fo, sizeof (PyFrameObject))
 844 +           != PS_OK) {
 845 +               iter->pdi_current = 0;
 846 +               return (0);
 847 +       }
 848 +
 849 +       iter->pdi_current = (uintptr_t)fo.f_back;
 850 +
 851 +       return (cur);
 852 +}
 853 +
 854 +/*
 855 + * Walk a list of Python PyThreadState objects.  The addr argument must be
 856 + * the address of a valid PyInterpreterState object.
 857 + */
 858 +pydb_iter_t *
 859 +pydb_thread_iter_init(pydb_agent_t *py, uintptr_t addr)
 860 +{
 861 +       pydb_iter_t *itr;
 862 +       PyInterpreterState is;
 863 +
 864 +       if (ps_pread(py->pdb_ph, (uintptr_t)addr, &is,
 865 +           sizeof (PyInterpreterState)) != PS_OK) {
 866 +               return (NULL);
 867 +       }
 868 +
 869 +       itr = malloc(sizeof (pydb_iter_t));
 870 +       if (itr == NULL) {
 871 +               return (NULL);
 872 +       }
 873 +
 874 +       itr->pdi_ph = py->pdb_ph;
 875 +       itr->pdi_current = (uintptr_t)is.tstate_head;
 876 +       itr->pdi_nextf = pydb_thread_iter_next;
 877 +
 878 +       return (itr);
 879 +}
 880 +
 881 +static uintptr_t
 882 +pydb_thread_iter_next(pydb_iter_t *iter)
 883 +{
 884 +       PyThreadState ts;
 885 +       uintptr_t cur;
 886 +
 887 +       cur = iter->pdi_current;
 888 +
 889 +       if (cur == 0) {
 890 +               return (cur);
 891 +       }
 892 +
 893 +       if (ps_pread(iter->pdi_ph, cur, &ts, sizeof (PyThreadState)) != PS_OK) {
 894 +               iter->pdi_current = 0;
 895 +               return (0);
 896 +       }
 897 +
 898 +       iter->pdi_current = (uintptr_t)ts.next;
 899 +
 900 +       return (cur);
 901 +}
 902 +
 903 +
 904 +uintptr_t
 905 +pydb_iter_next(pydb_iter_t *iter)
 906 +{
 907 +       return (iter->pdi_nextf(iter));
 908 +}
 909 +
 910 +void
 911 +pydb_iter_fini(pydb_iter_t *iter)
 912 +{
 913 +       if (iter == NULL) {
 914 +               return;
 915 +       }
 916 +
 917 +       free(iter);
 918 +}
 919 diff -ruN Python-2.6.7-orig/py_db/libpython26_db.h Python-2.6.7/py_db/libpython26_db.h
 920 --- Python-2.6.7-orig/py_db/libpython26_db.h    1970-01-01 00:00:00.000000000 +0000
 921 +++ Python-2.6.7/py_db/libpython26_db.h 2012-02-16 03:13:33.351318662 +0000
 922 @@ -0,0 +1,74 @@
 923 +/*
 924 + * CDDL HEADER START
 925 + *
 926 + * The contents of this file are subject to the terms of the
 927 + * Common Development and Distribution License (the "License").
 928 + * You may not use this file except in compliance with the License.
 929 + *
 930 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 931 + * or http://www.opensolaris.org/os/licensing.
 932 + * See the License for the specific language governing permissions
 933 + * and limitations under the License.
 934 + *
 935 + * When distributing Covered Code, include this CDDL HEADER in each
 936 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 937 + * If applicable, add the following below this CDDL HEADER, with the
 938 + * fields enclosed by brackets "[]" replaced with your own identifying
 939 + * information: Portions Copyright [yyyy] [name of copyright owner]
 940 + *
 941 + * CDDL HEADER END
 942 + */
 943 +/*
 944 + * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 945 + * Use is subject to license terms.
 946 + */
 947 +
 948 +#ifndef        _LIBPYTHON26_DB_H
 949 +#define        _LIBPYTHON26_DB_H
 950 +
 951 +#include <proc_service.h>
 952 +
 953 +#ifdef __cplusplus
 954 +extern "C" {
 955 +#endif
 956 +
 957 +/* Agent is opaque to library's consumers.  */
 958 +typedef struct pydb_agent pydb_agent_t;
 959 +
 960 +/*
 961 + * Library's debug version is 1.  Changes to interface should increase this
 962 + * number.
 963 + */
 964 +#define        PYDB_VERSION    1
 965 +
 966 +/* Agent creation/destruction routines */
 967 +extern pydb_agent_t    *pydb_agent_create(struct ps_prochandle *P, int vers);
 968 +extern void            pydb_agent_destroy(pydb_agent_t *py);
 969 +
 970 +/* Used by callers that know they are looking at a PyFrameObject */
 971 +extern int     pydb_get_frameinfo(pydb_agent_t *py, uintptr_t frame_addr,
 972 +    char *fbuf, size_t bufsz, int verbose);
 973 +
 974 +/*
 975 + * Used by callers that don't know if they're looking at PyFrameObject.
 976 + * Checks PC for traceable functions.
 977 + */
 978 +extern int     pydb_pc_frameinfo(pydb_agent_t *py, uintptr_t pc,
 979 +    uintptr_t frame_addr, char *fbuf, size_t bufsz);
 980 +
 981 +/* Iterator functions */
 982 +typedef struct pydb_iter pydb_iter_t;
 983 +
 984 +extern pydb_iter_t     *pydb_frame_iter_init(pydb_agent_t *py, uintptr_t addr);
 985 +extern pydb_iter_t     *pydb_interp_iter_init(pydb_agent_t *py,
 986 +    uintptr_t addr);
 987 +extern pydb_iter_t     *pydb_thread_iter_init(pydb_agent_t *py,
 988 +    uintptr_t addr);
 989 +extern void            pydb_iter_fini(pydb_iter_t *iter);
 990 +extern uintptr_t       pydb_iter_next(pydb_iter_t *iter);
 991 +
 992 +#ifdef __cplusplus
 993 +}
 994 +#endif
 995 +
 996 +#endif /* _LIBPYTHON26_DB_H */
 997 diff -ruN Python-2.6.7-orig/py_db/mapfile-vers Python-2.6.7/py_db/mapfile-vers
 998 --- Python-2.6.7-orig/py_db/mapfile-vers        1970-01-01 00:00:00.000000000 +0000
 999 +++ Python-2.6.7/py_db/mapfile-vers     2012-02-16 03:13:33.351553918 +0000
1000 @@ -0,0 +1,40 @@
1001 +#
1002 +# CDDL HEADER START
1003 +#
1004 +# The contents of this file are subject to the terms of the
1005 +# Common Development and Distribution License (the "License").
1006 +# You may not use this file except in compliance with the License.
1007 +#
1008 +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1009 +# or http://www.opensolaris.org/os/licensing.
1010 +# See the License for the specific language governing permissions
1011 +# and limitations under the License.
1012 +#
1013 +# When distributing Covered Code, include this CDDL HEADER in each
1014 +# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1015 +# If applicable, add the following below this CDDL HEADER, with the
1016 +# fields enclosed by brackets "[]" replaced with your own identifying
1017 +# information: Portions Copyright [yyyy] [name of copyright owner]
1018 +#
1019 +# CDDL HEADER END
1020 +#
1021 +
1022 +#
1023 +# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
1024 +# Use is subject to license terms.
1025 +#
1026 +
1027 +SUNWprivate_1.1 {
1028 +    global:
1029 +       pydb_agent_create;
1030 +       pydb_agent_destroy;
1031 +       pydb_frame_iter_init;
1032 +       pydb_get_frameinfo;
1033 +       pydb_pc_frameinfo;
1034 +       pydb_interp_iter_init;
1035 +       pydb_thread_iter_init;
1036 +       pydb_iter_fini;
1037 +       pydb_iter_next;
1038 +    local:
1039 +       *;
1040 +};