Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

best way to deal with python pdb flakiness re/stdout?

Tags:

python

pdb

If I have a program where stdout is redirected, my pdb prompts all go to the redirection, because the library was written to write to stdout.

Oftentimes this problem is subtle, causing me to think a program is hanging when it's really waiting for input.

How do people work around this? (Unfortunately, using other debuggers like winpdb is not an option).

like image 432
10 revs, 7 users 53% Avatar asked Dec 24 '09 20:12

10 revs, 7 users 53%


2 Answers

This answer is just to supplement Ned's, as a way of wrapping the pdb.py main() function in a manner which doesn't require copying 40 lines just to change one of them:

# sane_pdb.py: launch Pdb with stdout on original
import sys, pdb
def fixed_pdb(Pdb=pdb.Pdb):
    '''make Pdb() tied to original stdout'''
    return Pdb(stdout=sys.__stdout__)

if __name__ == '__main__':
    pdb.Pdb = fixed_pdb
    pdb.main()

I don't know if it actually works for the questioner's problem, but it does what Ned described...

like image 51
Peter Hansen Avatar answered Sep 29 '22 00:09

Peter Hansen


The problem here is that PDB uses Cmd class where by default:

use_rawinput = 1

It means that Cmd will use raw_input() method by default instead of sys.stdout.readline() to read from the console . This is done because raw_input() supports history (only if readline module is loaded) and other useful bits . The only issue is that raw_input() does not support redirection, so if you have a script:

#!/usr/bin/python
name=raw_input("Enter your name: ")

and run it

> python test.py
Enter your name: Alex

but, if you run it with output redirection it will stuck

> python test.py | tee log

this is exactly what PDB uses and why it's stuck as well. As I mentioned sys.stdin.readline() supports redirection and if you rewrite the above script using readline() it should work.

Back to the original issue all you need to do is to tell Cmd to not use raw_input():

Cmd.use_rawinput = 0

or

pdb = pdb.Pdb()
pdb.use_rawinput=0
pdb.set_trace()
like image 24
Alexander Starostin Avatar answered Sep 28 '22 22:09

Alexander Starostin