python/coverage: update to 7.6.5
[oi-userland.git] / components / python / python27 / patches / 14-py_db.patch
blob8bf7d010378b77e2261e05fcef7a9db959301865
1 This patch adds Python debugger support. It may be contributed upstream at
2 some point, but the suitability (or lack thereof) has not yet been determined.
4 --- Python-2.7.15/Makefile.pre.in 2018-08-23 19:21:55.679929900 +0000
5 +++ Python-2.7.15/Makefile.pre.in 2018-08-23 19:32:47.145140718 +0000
6 @@ -403,7 +403,7 @@ LIBRARY_OBJS= \
8 # Default target
9 all: @DEF_MAKE_ALL_RULE@
10 -build_all: check-clean-src $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks
11 +build_all: check-clean-src $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks build-py_db
13 # Check that the source is clean when building out of source.
14 check-clean-src:
15 @@ -856,6 +856,15 @@
17 $(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
19 +SHLIB_FLAGS = -shared -fpic
21 +libpython2.7_db.so.1.0: $(srcdir)/py_db/libpython27_db.c
22 + $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) $(SHLIB_FLAGS) $<
24 +build-py_db: libpython2.7_db.so.1.0
26 +install-py_db: libpython2.7_db.so.1.0
27 + $(INSTALL_SHARED) libpython2.7_db.so.1.0 $(DESTDIR)$(LIBDIR)
29 ######################################################################
31 @@ -920,7 +929,7 @@
32 $(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
34 # Install everything
35 -install: @FRAMEWORKINSTALLFIRST@ commoninstall bininstall maninstall @FRAMEWORKINSTALLLAST@
36 +install: @FRAMEWORKINSTALLFIRST@ commoninstall bininstall maninstall @FRAMEWORKINSTALLLAST@ install-py_db
37 if test "x$(ENSUREPIP)" != "xno" ; then \
38 case $(ENSUREPIP) in \
39 upgrade) ensurepip="--upgrade" ;; \
40 --- /dev/null
41 +++ Python-2.7.1/py_db/libpython27_db.c
42 @@ -0,0 +1,654 @@
43 +/*
44 + * CDDL HEADER START
45 + *
46 + * The contents of this file are subject to the terms of the
47 + * Common Development and Distribution License (the "License").
48 + * You may not use this file except in compliance with the License.
49 + *
50 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
51 + * or http://www.opensolaris.org/os/licensing.
52 + * See the License for the specific language governing permissions
53 + * and limitations under the License.
54 + *
55 + * When distributing Covered Code, include this CDDL HEADER in each
56 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
57 + * If applicable, add the following below this CDDL HEADER, with the
58 + * fields enclosed by brackets "[]" replaced with your own identifying
59 + * information: Portions Copyright [yyyy] [name of copyright owner]
60 + *
61 + * CDDL HEADER END
62 + */
63 +/*
64 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
65 + */
67 +#include <stdio.h>
68 +#include <stdlib.h>
69 +#include <string.h>
70 +#include <errno.h>
71 +#include <gelf.h>
73 +#include <Python.h>
74 +#include <frameobject.h>
76 +#include "libpython27_db.h"
77 +#if defined(_LP64)
78 +#include "libpython27_db_32.h"
79 +#endif /* _LP64 */
81 +/*
82 + * Because MDB always runs the debugger in the same datamodel as the target,
83 + * only functions that are used by the procfs part of this interface (or shared
84 + * between the two) are written as 64->32 aware.
85 + */
86 +typedef struct pydb_arch_ops {
87 + ssize_t (*strobj_readdata)(pydb_agent_t *, uintptr_t, unsigned char *,
88 + size_t);
89 + int (*frameinfo)(pydb_agent_t *, uintptr_t, char *,
90 + size_t, char *, size_t, int *);
91 +} pydb_arch_ops_t;
93 +struct pydb_agent {
94 + struct ps_prochandle *pdb_ph;
95 + int pdb_vers;
96 + int pdb_is_64bit;
97 + int pdb_datamodel;
98 + const pydb_arch_ops_t *pdb_ops;
99 +};
101 +typedef uintptr_t (*pdi_next_cb_t)(pydb_iter_t *);
103 +struct pydb_iter {
104 + struct ps_prochandle *pdi_ph;
105 + uintptr_t pdi_current;
106 + pdi_next_cb_t pdi_nextf;
109 +#define LIBPYTHON "libpython2.7.so"
111 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
113 +/* Generic interface to helper functions */
114 +static ssize_t pydb_strobj_readdata(pydb_agent_t *py, uintptr_t addr,
115 + unsigned char *buf, size_t buf_len);
116 +static int pydb_getlno(pydb_agent_t *py, uintptr_t lnotab_addr, int firstline,
117 + int lastinst);
118 +static int pydb_frameinfo(pydb_agent_t *py, uintptr_t addr, char *funcnm,
119 + size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
121 +/* datamodel specific implementation of helper functions */
122 +static ssize_t pydb_strobj_readdata_native(pydb_agent_t *py, uintptr_t addr,
123 + unsigned char *buf, size_t buf_len);
124 +static int pydb_frameinfo_native(pydb_agent_t *py, uintptr_t addr, char *funcnm,
125 + size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
127 +#if defined (_LP64)
128 +static ssize_t pydb_strobj_readdata_32(pydb_agent_t *py, uintptr_t addr,
129 + unsigned char *buf, size_t buf_len);
130 +static int pydb_frameinfo_32(pydb_agent_t *py, uintptr_t addr, char *funcnm,
131 + size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
132 +#endif /* _LP64 */
134 +static ssize_t pydb_strobj_readstr(pydb_agent_t *py, uintptr_t addr, char *buf,
135 + size_t len);
137 +/* Iterator function next routines. Plugable, configured by iterator init */
138 +static uintptr_t pydb_frame_iter_next(pydb_iter_t *iter);
139 +static uintptr_t pydb_interp_iter_next(pydb_iter_t *iter);
140 +static uintptr_t pydb_thread_iter_next(pydb_iter_t *iter);
142 +static const char *strbasename(const char *s);
144 +static const pydb_arch_ops_t arch_ops_native = {
145 + .frameinfo = pydb_frameinfo_native,
146 + .strobj_readdata = pydb_strobj_readdata_native,
149 +#if defined (_LP64)
150 +static const pydb_arch_ops_t arch_ops_32 = {
151 + .frameinfo = pydb_frameinfo_32,
152 + .strobj_readdata = pydb_strobj_readdata_32,
154 +#endif /* _LP64 */
156 +static const char *
157 +strbasename(const char *s)
159 + const char *p = strrchr(s, '/');
161 + if (p == NULL)
162 + return (s);
164 + return (++p);
167 +/* Agent creation / destruction routines */
169 +pydb_agent_t *
170 +pydb_agent_create(struct ps_prochandle *P, int vers)
172 + pydb_agent_t *py;
173 + int datamodel;
175 + if (vers != PYDB_VERSION) {
176 + errno = ENOTSUP;
177 + return (NULL);
180 + if (ps_pdmodel(P, &datamodel) != PS_OK) {
181 + return (NULL);
184 + py = (pydb_agent_t *)malloc(sizeof (pydb_agent_t));
185 + if (py == NULL) {
186 + return (NULL);
189 + py->pdb_ph = P;
190 + py->pdb_vers = vers;
191 + py->pdb_datamodel = datamodel;
192 + py->pdb_is_64bit = 0;
193 + py->pdb_ops = &arch_ops_native;
195 +#if defined (_LP64)
196 + py->pdb_is_64bit = (datamodel == PR_MODEL_LP64);
197 + if (!py->pdb_is_64bit) {
198 + py->pdb_ops = &arch_ops_32;
200 +#endif /* _LP64 */
202 + return (py);
205 +void
206 +pydb_agent_destroy(pydb_agent_t *py)
208 + if (py == NULL) {
209 + return;
212 + free(py);
215 +/* Helper functions */
216 +static int
217 +pydb_getlno(pydb_agent_t *py, uintptr_t lnotab_addr, int firstline,
218 + int lastinst)
220 + unsigned char lnotab[4096];
221 + ssize_t lnotab_len;
222 + int addr, line;
223 + int i;
225 + lnotab_len = pydb_strobj_readdata(py, lnotab_addr, lnotab,
226 + sizeof (lnotab));
227 + if (lnotab_len < 0) {
228 + return (-1);
231 + /*
232 + * Python's line number algorithm is arcane. See here for details:
233 + * http://svn.python.org/projects/python/trunk/Objects/lnotab_notes.txt
234 + */
236 + line = firstline;
237 + for (addr = i = 0; i < lnotab_len; i += 2) {
238 + if (addr + lnotab[i] > lastinst) {
239 + break;
241 + addr += lnotab[i];
242 + line += lnotab[i + 1];
245 + return (line);
248 +static ssize_t
249 +pydb_strobj_readdata(pydb_agent_t *py, uintptr_t addr, unsigned char *buf,
250 + size_t buf_len)
252 + return (py->pdb_ops->strobj_readdata(py, addr, buf, buf_len));
255 +static ssize_t
256 +pydb_strobj_readdata_native(pydb_agent_t *py, uintptr_t addr,
257 + unsigned char *buf, size_t buf_len)
259 + PyStringObject sobj;
260 + ssize_t obj_sz;
261 + ssize_t read_sz;
262 + psaddr_t straddr;
264 + /*
265 + * PyStringObjects are variable size. The size of the PyStringObject
266 + * struct is fixed, and known at compile time; however, the size of the
267 + * associated buffer is variable. The char[1] element at the end of the
268 + * structure contains the string, and the ob_size of the PyStringObject
269 + * indicates how much extra space was allocated to contain the string
270 + * buffer at the object's tail. Read in the fixed size portion of the
271 + * object first, and then read the contents of the data buffer into the
272 + * buffer passed by the caller.
273 + */
275 + if (ps_pread(py->pdb_ph, addr, &sobj, sizeof (PyStringObject))
276 + != PS_OK) {
277 + return (-1);
280 + obj_sz = (ssize_t)PyString_GET_SIZE(&sobj);
282 + read_sz = MIN(obj_sz, (ssize_t)buf_len);
283 + straddr = (psaddr_t)(addr + offsetof(PyStringObject, ob_sval));
285 + if (ps_pread(py->pdb_ph, straddr, buf, (size_t)read_sz) != PS_OK) {
286 + return (-1);
289 + return (read_sz);
292 +#if defined(_LP64)
293 +static ssize_t
294 +pydb_strobj_readdata_32(pydb_agent_t *py, uintptr_t addr,
295 + unsigned char *buf, size_t buf_len)
297 + PyStringObject32 sobj;
298 + ssize_t obj_sz;
299 + ssize_t read_sz;
300 + psaddr_t straddr;
302 + /*
303 + * PyStringObjects are variable size. The size of the PyStringObject
304 + * struct is fixed, and known at compile time; however, the size of the
305 + * associated buffer is variable. The char[1] element at the end of the
306 + * structure contains the string, and the ob_size of the PyStringObject
307 + * indicates how much extra space was allocated to contain the string
308 + * buffer at the object's tail. Read in the fixed size portion of the
309 + * object first, and then read the contents of the data buffer into the
310 + * buffer passed by the caller.
311 + */
313 + if (ps_pread(py->pdb_ph, addr, &sobj, sizeof (PyStringObject32))
314 + != PS_OK) {
315 + return (-1);
318 + obj_sz = (ssize_t)PyString_GET_SIZE32(&sobj);
320 + read_sz = MIN(obj_sz, (ssize_t)buf_len);
321 + straddr = (psaddr_t)(addr + offsetof(PyStringObject32, ob_sval));
323 + if (ps_pread(py->pdb_ph, straddr, buf, (size_t)read_sz) != PS_OK) {
324 + return (-1);
327 + return (read_sz);
329 +#endif /* _LP64 */
332 + * Most Python PyStringObjects contain strings, as one would expect. However,
333 + * due to some sleazy hackery in parts of the Python code, some string objects
334 + * are used as buffers for binary data. In the general case,
335 + * pydb_strobj_readstr() should be used to read strings out of string objects.
336 + * It wraps pydb_strobj_readdata(), which should be used by callers only when
337 + * trying to retrieve binary data. (This routine does some string cleanup).
338 + */
339 +static ssize_t
340 +pydb_strobj_readstr(pydb_agent_t *py, uintptr_t addr, char *buf,
341 + size_t buf_len)
343 + ssize_t read_sz;
345 + read_sz = pydb_strobj_readdata(py, addr, (unsigned char *)buf, buf_len);
347 + if (read_sz >= 0) {
348 + if (read_sz >= buf_len) {
349 + read_sz = buf_len - 1;
352 + buf[read_sz] = '\0';
355 + return (read_sz);
359 +static int
360 +pydb_frameinfo(pydb_agent_t *py, uintptr_t addr, char *funcnm,
361 + size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno)
363 + return (py->pdb_ops->frameinfo(py, addr, funcnm, funcnm_sz,
364 + filenm, filenm_sz, lineno));
367 +static int
368 +pydb_frameinfo_native(pydb_agent_t *py, uintptr_t addr, char *funcnm,
369 + size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno)
371 + PyFrameObject fo;
372 + PyCodeObject co;
373 + ssize_t rc;
375 + if (ps_pread(py->pdb_ph, addr, &fo, sizeof (PyFrameObject))
376 + != PS_OK) {
377 + return (-1);
380 + if (ps_pread(py->pdb_ph, (uintptr_t)fo.f_code, &co,
381 + sizeof (PyCodeObject)) != PS_OK) {
382 + return (-1);
385 + rc = pydb_strobj_readstr(py, (uintptr_t)co.co_name, funcnm, funcnm_sz);
386 + if (rc < 0) {
387 + return (-1);
390 + rc = pydb_strobj_readstr(py, (uintptr_t)co.co_filename, filenm,
391 + filenm_sz);
392 + if (rc < 0) {
393 + return (-1);
396 + *lineno = pydb_getlno(py, (uintptr_t)co.co_lnotab, co.co_firstlineno,
397 + fo.f_lasti);
398 + if (*lineno < 0) {
399 + return (-1);
402 + return (0);
405 +#if defined (_LP64)
406 +static int
407 +pydb_frameinfo_32(pydb_agent_t *py, uintptr_t addr, char *funcnm,
408 + size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno)
410 + PyFrameObject32 fo;
411 + PyCodeObject32 co;
412 + ssize_t rc;
414 + if (ps_pread(py->pdb_ph, addr, &fo, sizeof (PyFrameObject32))
415 + != PS_OK) {
416 + return (-1);
419 + if (ps_pread(py->pdb_ph, (uintptr_t)fo.f_code, &co,
420 + sizeof (PyCodeObject32)) != PS_OK) {
421 + return (-1);
424 + rc = pydb_strobj_readstr(py, (uintptr_t)co.co_name, funcnm, funcnm_sz);
425 + if (rc < 0) {
426 + return (-1);
429 + rc = pydb_strobj_readstr(py, (uintptr_t)co.co_filename, filenm,
430 + filenm_sz);
431 + if (rc < 0) {
432 + return (-1);
435 + *lineno = pydb_getlno(py, (uintptr_t)co.co_lnotab, co.co_firstlineno,
436 + fo.f_lasti);
437 + if (*lineno < 0) {
438 + return (-1);
441 + return (0);
444 +#endif /* _LP64 */
446 +/* Functions that are part of the library's interface */
449 + * Given the address of a PyFrameObject, and a buffer of a known size,
450 + * fill the buffer with a description of the frame.
451 + */
452 +int
453 +pydb_get_frameinfo(pydb_agent_t *py, uintptr_t frame_addr, char *fbuf,
454 + size_t bufsz, int verbose)
456 + char funcname[1024];
457 + char filename[1024];
458 + char *fn;
459 + int lineno;
460 + int length = (py->pdb_is_64bit ? 16 : 8);
461 + int rc;
463 + rc = pydb_frameinfo(py, frame_addr, funcname, sizeof (funcname),
464 + filename, sizeof (filename), &lineno);
465 + if (rc < 0) {
466 + return (-1);
469 + if (!verbose) {
470 + fn = (char *)strbasename(filename);
471 + } else {
472 + fn = filename;
475 + (void) snprintf(fbuf, bufsz, "%0.*lx %s:%d %s()\n", length,
476 + frame_addr, fn, lineno, funcname);
478 + return (0);
482 + * Return a description about a PyFrameObject, if the object is
483 + * actually a PyFrameObject. In this case, the pc argument is checked
484 + * to make sure that it came from a function that takes a PyFrameObject
485 + * as its first (argv[0]) argument.
486 + */
487 +int
488 +pydb_pc_frameinfo(pydb_agent_t *py, uintptr_t pc, uintptr_t frame_addr,
489 + char *fbuf, size_t bufsz)
491 + char funcname[1024];
492 + char filename[1024];
493 + int lineno;
494 + int rc;
495 + ps_sym_t psym;
497 + /*
498 + * If PC doesn't match PyEval_EvalFrameEx in either libpython
499 + * or the executable, don't decode it.
500 + */
501 + if (ps_pglobal_sym(py->pdb_ph, LIBPYTHON, "PyEval_EvalFrameEx", &psym)
502 + != PS_OK) {
503 + return (-1);
506 + /* If symbol found, ensure that PC falls within PyEval_EvalFrameEx. */
507 + if (pc < psym.st_value || pc > psym.st_value + psym.st_size) {
508 + return (-1);
511 + rc = pydb_frameinfo(py, frame_addr, funcname, sizeof (funcname),
512 + filename, sizeof (filename), &lineno);
513 + if (rc < 0) {
514 + return (-1);
517 + (void) snprintf(fbuf, bufsz, "[ %s:%d (%s) ]\n", filename, lineno,
518 + funcname);
520 + return (0);
524 + * Walks the list of PyInterpreterState objects. If caller doesn't
525 + * supply address of list, this method will look it up.
526 + */
527 +pydb_iter_t *
528 +pydb_interp_iter_init(pydb_agent_t *py, uintptr_t addr)
530 + pydb_iter_t *itr;
531 + uintptr_t i_addr;
532 + int rc;
534 + if (addr == 0) {
535 + rc = ps_pglobal_lookup(py->pdb_ph, LIBPYTHON, "interp_head",
536 + (psaddr_t *)&addr);
537 + if (rc != PS_OK) {
538 + return (NULL);
542 + if (ps_pread(py->pdb_ph, (uintptr_t)addr, &i_addr, sizeof (uintptr_t))
543 + != PS_OK) {
544 + return (NULL);
547 + itr = malloc(sizeof (pydb_iter_t));
548 + if (itr == NULL) {
549 + return (NULL);
552 + itr->pdi_ph = py->pdb_ph;
553 + itr->pdi_current = i_addr;
554 + itr->pdi_nextf = pydb_interp_iter_next;
556 + return (itr);
559 +static uintptr_t
560 +pydb_interp_iter_next(pydb_iter_t *iter)
562 + PyInterpreterState st;
563 + uintptr_t cur;
565 + cur = iter->pdi_current;
567 + if (cur == 0) {
568 + return (cur);
571 + if (ps_pread(iter->pdi_ph, cur, &st, sizeof (PyInterpreterState))
572 + != PS_OK) {
573 + iter->pdi_current = 0;
574 + return (0);
577 + iter->pdi_current = (uintptr_t)st.next;
579 + return (cur);
583 + * Walk a list of Python PyFrameObjects. The addr argument must be
584 + * the address of a valid PyThreadState object.
585 + */
586 +pydb_iter_t *
587 +pydb_frame_iter_init(pydb_agent_t *py, uintptr_t addr)
589 + pydb_iter_t *itr;
590 + PyThreadState ts;
592 + if (ps_pread(py->pdb_ph, (uintptr_t)addr, &ts, sizeof (PyThreadState))
593 + != PS_OK) {
594 + return (NULL);
597 + itr = malloc(sizeof (pydb_iter_t));
598 + if (itr == NULL) {
599 + return (NULL);
602 + itr->pdi_ph = py->pdb_ph;
603 + itr->pdi_current = (uintptr_t)ts.frame;
604 + itr->pdi_nextf = pydb_frame_iter_next;
606 + return (itr);
609 +static uintptr_t
610 +pydb_frame_iter_next(pydb_iter_t *iter)
612 + PyFrameObject fo;
613 + uintptr_t cur;
615 + cur = iter->pdi_current;
617 + if (cur == 0) {
618 + return (cur);
621 + if (ps_pread(iter->pdi_ph, cur, &fo, sizeof (PyFrameObject))
622 + != PS_OK) {
623 + iter->pdi_current = 0;
624 + return (0);
627 + iter->pdi_current = (uintptr_t)fo.f_back;
629 + return (cur);
633 + * Walk a list of Python PyThreadState objects. The addr argument must be
634 + * the address of a valid PyInterpreterState object.
635 + */
636 +pydb_iter_t *
637 +pydb_thread_iter_init(pydb_agent_t *py, uintptr_t addr)
639 + pydb_iter_t *itr;
640 + PyInterpreterState is;
642 + if (ps_pread(py->pdb_ph, (uintptr_t)addr, &is,
643 + sizeof (PyInterpreterState)) != PS_OK) {
644 + return (NULL);
647 + itr = malloc(sizeof (pydb_iter_t));
648 + if (itr == NULL) {
649 + return (NULL);
652 + itr->pdi_ph = py->pdb_ph;
653 + itr->pdi_current = (uintptr_t)is.tstate_head;
654 + itr->pdi_nextf = pydb_thread_iter_next;
656 + return (itr);
659 +static uintptr_t
660 +pydb_thread_iter_next(pydb_iter_t *iter)
662 + PyThreadState ts;
663 + uintptr_t cur;
665 + cur = iter->pdi_current;
667 + if (cur == 0) {
668 + return (cur);
671 + if (ps_pread(iter->pdi_ph, cur, &ts, sizeof (PyThreadState)) != PS_OK) {
672 + iter->pdi_current = 0;
673 + return (0);
676 + iter->pdi_current = (uintptr_t)ts.next;
678 + return (cur);
682 +uintptr_t
683 +pydb_iter_next(pydb_iter_t *iter)
685 + return (iter->pdi_nextf(iter));
688 +void
689 +pydb_iter_fini(pydb_iter_t *iter)
691 + if (iter == NULL) {
692 + return;
695 + free(iter);
697 diff --git Python-2.7.1/py_db/libpython27_db.h Python-2.7.1/py_db/libpython27_db.h
698 new file mode 100644
699 --- /dev/null
700 +++ Python-2.7.1/py_db/libpython27_db.h
701 @@ -0,0 +1,73 @@
703 + * CDDL HEADER START
705 + * The contents of this file are subject to the terms of the
706 + * Common Development and Distribution License (the "License").
707 + * You may not use this file except in compliance with the License.
709 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
710 + * or http://www.opensolaris.org/os/licensing.
711 + * See the License for the specific language governing permissions
712 + * and limitations under the License.
714 + * When distributing Covered Code, include this CDDL HEADER in each
715 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
716 + * If applicable, add the following below this CDDL HEADER, with the
717 + * fields enclosed by brackets "[]" replaced with your own identifying
718 + * information: Portions Copyright [yyyy] [name of copyright owner]
720 + * CDDL HEADER END
721 + */
723 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
724 + */
726 +#ifndef _LIBPYTHON27_DB_H
727 +#define _LIBPYTHON27_DB_H
729 +#include <proc_service.h>
731 +#ifdef __cplusplus
732 +extern "C" {
733 +#endif
735 +/* Agent is opaque to library's consumers. */
736 +typedef struct pydb_agent pydb_agent_t;
739 + * Library's debug version is 1. Changes to interface should increase this
740 + * number.
741 + */
742 +#define PYDB_VERSION 1
744 +/* Agent creation/destruction routines */
745 +extern pydb_agent_t *pydb_agent_create(struct ps_prochandle *P, int vers);
746 +extern void pydb_agent_destroy(pydb_agent_t *py);
748 +/* Used by callers that know they are looking at a PyFrameObject */
749 +extern int pydb_get_frameinfo(pydb_agent_t *py, uintptr_t frame_addr,
750 + char *fbuf, size_t bufsz, int verbose);
753 + * Used by callers that don't know if they're looking at PyFrameObject.
754 + * Checks PC for traceable functions.
755 + */
756 +extern int pydb_pc_frameinfo(pydb_agent_t *py, uintptr_t pc,
757 + uintptr_t frame_addr, char *fbuf, size_t bufsz);
759 +/* Iterator functions */
760 +typedef struct pydb_iter pydb_iter_t;
762 +extern pydb_iter_t *pydb_frame_iter_init(pydb_agent_t *py, uintptr_t addr);
763 +extern pydb_iter_t *pydb_interp_iter_init(pydb_agent_t *py,
764 + uintptr_t addr);
765 +extern pydb_iter_t *pydb_thread_iter_init(pydb_agent_t *py,
766 + uintptr_t addr);
767 +extern void pydb_iter_fini(pydb_iter_t *iter);
768 +extern uintptr_t pydb_iter_next(pydb_iter_t *iter);
770 +#ifdef __cplusplus
772 +#endif
774 +#endif /* _LIBPYTHON27_DB_H */
775 diff --git Python-2.7.1/py_db/libpython27_db_32.h Python-2.7.1/py_db/libpython27_db_32.h
776 new file mode 100644
777 --- /dev/null
778 +++ Python-2.7.1/py_db/libpython27_db_32.h
779 @@ -0,0 +1,121 @@
781 + * CDDL HEADER START
783 + * The contents of this file are subject to the terms of the
784 + * Common Development and Distribution License (the "License").
785 + * You may not use this file except in compliance with the License.
787 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
788 + * or http://www.opensolaris.org/os/licensing.
789 + * See the License for the specific language governing permissions
790 + * and limitations under the License.
792 + * When distributing Covered Code, include this CDDL HEADER in each
793 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
794 + * If applicable, add the following below this CDDL HEADER, with the
795 + * fields enclosed by brackets "[]" replaced with your own identifying
796 + * information: Portions Copyright [yyyy] [name of copyright owner]
798 + * CDDL HEADER END
799 + */
801 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
802 + */
804 +#ifndef _LIBPYTHON27_DB_32_H
805 +#define _LIBPYTHON27_DB_32_H
807 +#ifdef __cplusplus
808 +extern "C" {
809 +#endif
811 +#include <sys/types.h>
814 + * Define 32-bit Python data structures for use by the 64-bit debugger. This
815 + * is so that a 64-bit debugger may properly examine a 32-bit process.
817 + * In many cases, the debug library is only concerned with a few fields in the
818 + * Python structure. In that case, the other ancillary fields are elided.
819 + */
821 +typedef uint32_t uintptr32_t;
822 +typedef int32_t Py_ssize32_t;
824 +typedef struct _is32 {
825 + uintptr32_t next;
826 + uintptr32_t tstate_head;
827 +} PyInterpreterState32;
829 +typedef struct _ts32 {
830 + uintptr32_t next;
831 + uintptr32_t interp;
832 + uintptr32_t frame;
833 +} PyThreadState32;
835 +#define PyObject_HEAD32 \
836 + Py_ssize32_t ob_refcnt; \
837 + uintptr32_t ob_type;
839 +#define PyObject_VAR_HEAD32 \
840 + PyObject_HEAD32 \
841 + Py_ssize32_t ob_size;
843 +typedef struct {
844 + PyObject_HEAD32
845 +} PyObject32;
847 +typedef struct {
848 + PyObject_VAR_HEAD32
849 +} PyVarObject32;
851 +typedef struct {
852 + PyObject_VAR_HEAD32
853 + int32_t ob_shash;
854 + int ob_sstate;
855 + char ob_sval[1];
856 +} PyStringObject32;
858 +#define Py_SIZE32(ob) (((PyVarObject32*)(ob))->ob_size)
859 +#define PyString_GET_SIZE32(op) Py_SIZE32(op)
860 +#define PyString_AS_STRING32(op) (((PyStringObject32 *)(op))->ob_sval)
862 +typedef struct {
863 + PyObject_VAR_HEAD32
864 + uintptr32_t f_back;
865 + uintptr32_t f_code;
866 + uintptr32_t f_builtins;
867 + uintptr32_t f_globals;
868 + uintptr32_t f_locals;
869 + uintptr32_t f_valuestack;
870 + uintptr32_t f_stacktop;
871 + uintptr32_t f_trace;
872 + uintptr32_t f_exc_typpe, f_exc_value, f_exc_traceback;
873 + uintptr32_t f_tstate;
874 + int f_lasti;
875 + int f_lineno;
876 +} PyFrameObject32;
878 +typedef struct {
879 + PyObject_HEAD32
880 + int co_argcount;
881 + int co_nlocals;
882 + int co_stacksize;
883 + int co_flags;
884 + uintptr32_t co_code;
885 + uintptr32_t co_consts;
886 + uintptr32_t co_names;
887 + uintptr32_t co_varnames;
888 + uintptr32_t co_freevars;
889 + uintptr32_t co_cellvars;
890 + uintptr32_t co_filename;
891 + uintptr32_t co_name;
892 + int co_firstlineno;
893 + uintptr32_t co_lnotab;
894 +} PyCodeObject32;
896 +#ifdef __cplusplus
898 +#endif
900 +#endif /* _LIBPYTHON27_DB_32_H */
901 diff --git Python-2.7.1/py_db/mapfile-vers Python-2.7.1/py_db/mapfile-vers
902 new file mode 100644
903 --- /dev/null
904 +++ Python-2.7.1/py_db/mapfile-vers
905 @@ -0,0 +1,39 @@
907 +# CDDL HEADER START
909 +# The contents of this file are subject to the terms of the
910 +# Common Development and Distribution License (the "License").
911 +# You may not use this file except in compliance with the License.
913 +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
914 +# or http://www.opensolaris.org/os/licensing.
915 +# See the License for the specific language governing permissions
916 +# and limitations under the License.
918 +# When distributing Covered Code, include this CDDL HEADER in each
919 +# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
920 +# If applicable, add the following below this CDDL HEADER, with the
921 +# fields enclosed by brackets "[]" replaced with your own identifying
922 +# information: Portions Copyright [yyyy] [name of copyright owner]
924 +# CDDL HEADER END
928 +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
931 +SUNWprivate_1.1 {
932 + global:
933 + pydb_agent_create;
934 + pydb_agent_destroy;
935 + pydb_frame_iter_init;
936 + pydb_get_frameinfo;
937 + pydb_pc_frameinfo;
938 + pydb_interp_iter_init;
939 + pydb_thread_iter_init;
940 + pydb_iter_fini;
941 + pydb_iter_next;
942 + local:
943 + *;