@@ -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