Live data from Hacker News

Bug #915: Please help

nedbatchelder.com

91–97 of 97 posts

Re: Bug #915: Please help

#91
post #19
post #9

Earlier quoted context omitted.

Its cousin diff is also very handy.

Not a command line guru, but this looks interesting. Does it compare outputs of two commands? How does it do it?

it does[0] you are redirecting stdout of both of the subprocesses (the things in brackets) to the stdin of the diff command (I think it creates two different input streams, that diff knows how to compare).

[0] http://tldp.org/LDP/abs/html/process-sub.html

Re: Bug #915: Please help

#92

This doesn't quite get all the way there, but the failure is being caused by the closure of a _io.FileIO due to GC, which happens to have the same fd as the sqlite database. The closure happens in the middle of a SQLite operation, which causes a subsequent flock() call to fail. strace log from the failure: open("/home/travis/apprise-api/.coverage", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 31 fstat(31, {st_mode=S_IFREG|0644,…

OK, I found the root cause. The test harness uses mock to cause NamedTemporaryFile to fail in a few places: with patch('tempfile._TemporaryFileWrapper') as mock_ntf: mock_ntf.side_effect = OSError() Unfortunately tempfile.NamedTemporaryFile is not properly set up to detect failures from tempfile._TemporaryFileWrapper: try: file = _io.open(fd, mode, buffering=buffering, newline=newline, encoding=encoding) return _Temp…

Here's Ned's blog post describing the solution: https://nedbatchelder.com/blog/202001/bug_915_solved.html

Re: Bug #915: Please help

#93
post #82

Earlier quoted context omitted.

Impressive debugging expertise! relevant history: https://bugs.python.org/issue21058 https://bugs.python.org/issue26385

Wacky: the patch given in the initial submission of issue21058 is correct, but the patch that was actually committed incorrectly placed the wrapper inside the try block.

Interesting, that bug/patch was written by a guy I worked with at weta. He was always pushing code past its breaking point. I remember reading this bug before.

Looks like his fix didn’t have this bug. It may have been modified later, his patch was from 2014.

Re: Bug #915: Please help

#94

Earlier quoted context omitted.

I basically set up my GDB with commands to stop on a specific pattern of "lseek, then close", and if the pattern isn't met it just automatically continues the program. This is what the gdb script looks like: set height 0 catch syscall close catch syscall read catch syscall lseek disable 1 2 commands 2 disable 1 2 continue end commands 3 if $rdi == 31 enable 1 2 continue else continue end end The lseek catchpoint (3)…

and you can do it in a rr trace on linux I think if its hard to reproduce which sometimes happen with similar programs

... wow. For other people, RR is a debugging tool for recording and playing back program execution. During the replay phase, you get great gdb debugger support, including running code backwards to find bugs.

It's not a toy: it can debug Google Chrome, Libre Office, and QEMU. However, RR is Linux-only.

Thanks alehander42!

Ref: https://en.wikipedia.org/wiki/Rr_(debugging)

Re: Bug #915: Please help

#95

Earlier quoted context omitted.

OK, I found the root cause. The test harness uses mock to cause NamedTemporaryFile to fail in a few places: with patch('tempfile._TemporaryFileWrapper') as mock_ntf: mock_ntf.side_effect = OSError() Unfortunately tempfile.NamedTemporaryFile is not properly set up to detect failures from tempfile._TemporaryFileWrapper: try: file = _io.open(fd, mode, buffering=buffering, newline=newline, encoding=encoding) return _Temp…

Very nice work. > I don't know who's fault this ultimately is, but it does illustrate a possible danger of mock testing when messing with the internals of other libraries. It doesn't look like there's any way that _TemporaryFileWrapper() could throw an OSError. I'd consider that mock a bug.

It's also why you keep your try/catch blocks as small as possible. In this case, if the return was outside, which it probably should've been, then the error would've bubbled up instead of causing I/O failure.

Re: Bug #915: Please help

#96

Earlier quoted context omitted.

This is fantastic. I thought I was pretty good at gdb, but this is next level (and it isn't complicated). I've never seen any resource on "how to gdb a really gnarly bug"; this is a great example.

Debuggers are great! They're printf debugging, except that your printf can respond to the program state almost arbitrarily at runtime; not only that, they can modify the program state and can do so from a lot more lenient environment than your compiler would usually allow you to do. An advanced user can end up doing more programming in the debugger than outside of it.

Glad to see people writing in C-like languages finally get a taste of lisp programs ;)

Re: Bug #915: Please help

#97

This doesn't quite get all the way there, but the failure is being caused by the closure of a _io.FileIO due to GC, which happens to have the same fd as the sqlite database. The closure happens in the middle of a SQLite operation, which causes a subsequent flock() call to fail. strace log from the failure: open("/home/travis/apprise-api/.coverage", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 31 fstat(31, {st_mode=S_IFREG|0644,…

OK, I found the root cause. The test harness uses mock to cause NamedTemporaryFile to fail in a few places: with patch('tempfile._TemporaryFileWrapper') as mock_ntf: mock_ntf.side_effect = OSError() Unfortunately tempfile.NamedTemporaryFile is not properly set up to detect failures from tempfile._TemporaryFileWrapper: try: file = _io.open(fd, mode, buffering=buffering, newline=newline, encoding=encoding) return _Temp…

What did he win?
Post reply on HN