Skip to content

Commit 62623ed

Browse files
committed
Fix line numbers for python traces.
1 parent b111dd7 commit 62623ed

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

‎python.cc‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,28 @@ pthreadTidOffset(const Process &proc, size_t *offsetp)
3333
return false;
3434
}
3535

36+
// This reimplements PyCode_Addr2Line
37+
int getLine(Process *proc, const PyCodeObject *code, const PyFrameObject *frame)
38+
{
39+
PyVarObject lnotab;
40+
proc->io->readObj(Elf_Addr(code->co_lnotab), &lnotab);
41+
unsigned char linedata[lnotab.ob_size];
42+
proc->io->readObj(Elf_Addr(code->co_lnotab) + offsetof(PyStringObject, ob_sval),
43+
&linedata[0], lnotab.ob_size);
44+
int line = code->co_firstlineno;
45+
int addr = 0;
46+
unsigned char *p = linedata;
47+
unsigned char *e = linedata + lnotab.ob_size;
48+
while (p < e) {
49+
addr += *p++;
50+
if (addr > frame->f_lasti) {
51+
break;
52+
}
53+
line += *p++;
54+
}
55+
return line;
56+
}
57+
3658
/*
3759
* process one python thread in an interpreter, at remote addr "ptr".
3860
* returns the address of the next thread on the list.
@@ -58,9 +80,10 @@ doPyThread(Process &proc, std::ostream &os, Elf_Addr ptr)
5880
proc.io->readObj(framePtr, &frame);
5981
PyCodeObject code;
6082
proc.io->readObj(Elf_Addr(frame.f_code), &code);
83+
auto lineNo = getLine(&proc, &code, &frame);
6184
auto func = proc.io->readString(Elf_Addr(code.co_name) + offsetof(PyStringObject, ob_sval));
6285
auto file = proc.io->readString(Elf_Addr(code.co_filename) + offsetof(PyStringObject, ob_sval));
63-
os << "\t" << func << " in " << file << ":" << frame.f_lineno << "\n";
86+
os << "\t" << func << " in " << file << ":" << lineNo << "\n";
6487
}
6588
return Elf_Addr(thread.next);
6689
}

0 commit comments

Comments
 (0)