[Idle-dev] strange bug

Kurt B. Kaiser kbk at shore.net
Sun Mar 19 08:08:08 CET 2006


Bruce Sherwood <Bruce_Sherwood at ncsu.edu> writes:

Sorry it took so long for me to get to this.

> This year we have about 1600 engineering and science students at
> NCSU writing VPython programs as the computational physics component
> of the introductory calculus-based physics course. Until this
> semester we (of course) had almost zero losses of editing work. We
> have auto-save enabled, so F5 saves the student's work before
> running the program.

It shouldn't make any difference whether autosave is enabled, except
possibly that the students might be closing the VPython graphics
window more quickly when using it.

> In December the computer environment on the Windows machines in the
> physics labs was revised, possibly not entirely competently. And now
> for the first time many students are losing their work, which is a
> nightmare. Press F5, see the VPython 3d graphics window, and (very
> occasionally, not reproducibly) the program freezes. Student goes to
> monitor and kills the process and also the IDLE-associated processes
> (edit window and shell window). Student now finds that the source
> file exists but is zero-length and empty.

The code which saves the file is single threaded, and the file is
saved before the subprocess is initialized.

ScriptBinding.run_module_event() calls ScriptBinding.getfilename(),
which (if the Edit window hasn't been saved) calls IOBinding.save().
The latter calls IOBinding.writefile(), which opens, writes, and
closes the file (within a try/except) before returning.  If there is
an IOError, a dialog is raised to notify the user.  There's not a lot
of C code to implementing the file open/write/close operations, and I
reviewed it.  It all looks pretty solid, and hasn't changed for quite
awhile.

Opening the file truncates it to zero length.  The contents of the
Text object are written to the file, then the file is closed.  As I
said, from a Python point of view all of that happens before the
subprocess is restarted.

When I first read your email, I figured maybe IDLE wasn't closing
the file after writing it.  But that's not the case, it is closed.

> If the student just kills the graphics windows (using the Windows
> monitor), IDLE runs and all is well, but it has taken awhile to
> learn this procedure. 

Of course, that's one of the main benefits of splitting up the
GUI and the subprocess.  You can kill off the errant subprocess
without losing your state.

> A possible reason for the graphics window freezing up is that the
> December reworking of the machine environment left us with poor
> graphics drivers with respect to OpenGL, but who knows. 

When the subprocess hangs or crashes because of drivers (or an error
in VPython), nothing can be done to interrupt/restart the subprocess
because the socket control thread isn't getting a chance to run.

> The freeze seems to happen more often if there are many processes
> and/or windows active, or at least that's the folklore (the machines
> only have 256 MB of memory).

You might be running out of memory, and that could affect the file
writing to the AFS.

It rather sounds like Windows or the AFS interface is buffering the
file sync/close somehow, and when the IDLE GUI is terminated the
buffer is dropped.

It must take the students 20 seconds to kill the VPython graphics
window.  The file should have been written and closed long before.

> To add to the complexity, students normally connect to their
> campus-wide AFS account which shows up as an extra disk drive on
> Windows, and they edit the AFS source file in IDLE.

Have you ever seen the problem when not using the AFS?

> Does this ring any bells?

I'm afraid it doesn't.  The code in that part of both IDLE and Python
has been stable for some time.

Data loss is the worst kind of error, and quite discouraging to
students.  I'd certainly like to see this fixed.

One possibility would be to add a f.flush() call before f.close().
It's not unusual for an OS to delay writing out a buffer.  It 
seems unusual to me to destroy an unwritten buffer when the
process that wrote to it is destroyed, but it's possible.

Try adding one line of code in IOBinding.py:IOBinding.writefile() :


f = open(filename, "wb")
f.write(chars)
f.flush()              <---------!!
f.close()

I'm going to try to add that to the upcoming 2.4.3.  It can't hurt.

-- 
KBK


More information about the IDLE-dev mailing list