forked from peadar/pstack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython2.cc
More file actions
115 lines (102 loc) · 3.83 KB
/
python2.cc
File metadata and controls
115 lines (102 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <python2.7/Python.h>
#include <python2.7/frameobject.h>
#include <python2.7/longintrepr.h>
#include "libpstack/python.h"
template<> std::set<const PythonTypePrinter<2> *> PythonTypePrinter<2>::all = std::set<const PythonTypePrinter<2> *>();
template<>
char PythonTypePrinter<2>::pyBytesType[] = "PyString_Type";
/**
* @brief Reads a Python2 string
*
* @param r The reader used
* @param addr Address of PyStringObject
* @return std::string
*/
template <> std::string readString<2>(const Reader &r, const Elf::Addr addr) {
return r.readString(addr + offsetof(PyBytesObject, ob_sval));
}
class BoolPrint : public PythonTypePrinter<2> {
Elf::Addr print(const PythonPrinter<2> *pc, const PyObject *pyo, const PyTypeObject *, Elf::Addr) const override {
auto pio = (const PyIntObject *)pyo;
pc->os << (pio->ob_ival ? "True" : "False");
return 0;
}
const char *type() const override { return "PyBool_Type"; }
bool dupdetect() const override { return false; }
};
static BoolPrint boolPrinter;
class ClassPrinter : public PythonTypePrinter<2> {
Elf::Addr print(const PythonPrinter<2> *pc, const PyObject *po, const PyTypeObject *, Elf::Addr) const override {
auto pco = reinterpret_cast<const PyClassObject *>(po);
pc->os << "<class ";
pc->print(intmax_t(pco->cl_name));
pc->os << ">";
return 0;
};
const char *type() const override { return "PyClass_Type"; }
bool dupdetect() const override { return true; }
};
static ClassPrinter classPrinter;
class DictPrinter : public PythonTypePrinter<2> {
Elf::Addr print(const PythonPrinter<2> *pc, const PyObject *pyo, const PyTypeObject *, Elf::Addr) const override {
PyDictObject *pdo = (PyDictObject *)pyo;
if (pdo->ma_used == 0)
return 0;
for (Py_ssize_t i = 0; i < pdo->ma_mask ; ++i) {
PyDictEntry pde = readPyObj<2, PyDictEntry>(*pc->proc.io, Elf::Addr(pdo->ma_table + i));
if (pde.me_value == nullptr)
continue;
if (pde.me_key != nullptr) {
pc->os << pc->prefix();
pc->print(Elf::Addr(pde.me_key));
pc->os << ": ";
pc->print(Elf::Addr(pde.me_value));
pc->os << "\n";
}
}
return 0;
}
const char *type() const override { return "PyDict_Type"; }
bool dupdetect() const override { return true; }
};
static DictPrinter dictPrinter;
class InstancePrinter : public PythonTypePrinter<2> {
Elf::Addr print(const PythonPrinter<2> *pc, const PyObject *pyo, const PyTypeObject *, Elf::Addr) const override {
const auto pio = reinterpret_cast<const PyInstanceObject *>(pyo);
pc->depth++;
pc->os << "\n" << pc->prefix() << "class: ";
pc->depth++;
pc->print(Elf::Addr(pio->in_class));
pc->depth--;
pc->os << "\n" << pc->prefix() << "dict: \n";
pc->depth++;
pc->print(Elf::Addr(pio->in_dict));
pc->depth--;
pc->depth--;
return 0;
}
const char *type() const override { return "PyInstance_Type"; }
bool dupdetect() const override { return true; }
};
static InstancePrinter instancePrinter;
class IntPrint : public PythonTypePrinter<2> {
Elf::Addr print(const PythonPrinter<2> *pc, const PyObject *pyo, const PyTypeObject *, Elf::Addr) const override {
auto pio = (const PyIntObject *)pyo;
pc->os << pio->ob_ival;
return 0;
}
const char *type() const override { return "PyInt_Type"; }
bool dupdetect() const override { return false; }
};
template <typename T, int pyv>
ssize_t
pyRefcnt(const T *o) {
return o->ob_refcnt;
}
template <int pyv, typename T> const PyTypeObject *
pyObjtype(const T *o) {
return o->ob_type;
}
static IntPrint intPrinter;
#include "python.tcc"
template struct PythonPrinter<2>;