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