You can't spell "evil" without "vi".

Rob Landley rob at landley.net
Tue Oct 14 21:18:10 UTC 2008


On Tuesday 14 October 2008 05:18:44 Denys Vlasenko wrote:
> On Tuesday 14 October 2008 10:48:54 am Rob Landley wrote:
> > On Sunday 12 October 2008 23:48:22 Rob Landley wrote:
> > > Next time it reads a buffer, it starts with the last character of a
> > > cursor left sequence: capital D.  Capital D is "delete to end of line",
> > > which it does.
> > >
> > > So basically, busybox vi is corrupting your data when you cursor around
> > > in a file on a loaded system.  Wheee...
> >
> > Hmmm...  I redid the readit() code to only read ahead when processing an
> > escape sequence.  (This let me shrink the readahead buffer to 8 bytes,
> > actually 5 but with 32 bit alignment 8 makes more sense.  Bloatcheck says
> > I shrunk the code by 17 bytes.)
>
> Disregard my previous patch, I just looked at your code and it's
> as good but it's smaller than mine, so let's use yours.
>
> > Unfortunately, this mitigated the problem a bit, but didn't actually
> > _fix_ it. It happens less often, but I can still trigger it.
> >
> > I _think_ this is actually a qemu issue.  The escape sequences are being
> > generated by the host Linux, which are then sent to the qemu process over
> > a virtual serial console, which breaks them down into individual bytes
> > with an interrupt for each.
> >
> > This means that the blocking we're depending on to parse escape sequences
> > doesn't work over a serial console.  You _can get an escape character by
> > itself with poll saying there's no more data, and then on the next clock
> > cycle you can get a "[D".
> >
> > Hmmm...
> >
> > Ok, making poll wait 300 miliseconds before deciding there's no next
> > character in a pending escape sequence seems to have fixed it.  (At least
> > I can't reproduce the problem under qemu anymore.)
>
> Please document this next time, or someone else might come later
> and delete the timeout. I did this a few mins ago :( will fix it now.

I did a comment in the checkin, but a comment in the source makes sense too.

> Did you try something smaller than 300ms?

You could probably go below 300ms (I was pondering 250ms or even 100ms), but 
there's no perfect minimum value.  It's not that anybody's going to use this 
code with a 300 bps modem, but on a loaded system where a scheduler delay 
gets inserted in between receiving the escape and receiving the "[", deleting 
to end of line is a bad failure mode to encounter.  (Especially since you 
don't always _notice_ that cursoring past something ate part of your file.)

Since the blocking gets destroyed on a serial connection, the delay is what 
strings the escape sequence characters back together, and asking "how long 
might this code be interrupted by other activity on the system" has no good 
answer, especially on slow systems.  It _could_ be interrupted for a full 
second if the executable page gets discarded due to memory constraints, and 
has to be faulted back in from slow storage.

Also, note that this delay is just until the system acts on the escape 
character without another character pressed.  If you type esc-colon-w-q 
really fast, it'll act on it immediately, because that's not a recognized 
escape sequence and it falls back to interpreting them as individual 
characters as soon as it _knows_ this isn't an escape sequence.  It knows 
when the timeout occurs, and it knows when the pattern can't be an escape 
sequence it knows about.

Alas, the above is a bit long to put in a comment in the source code. :)

Rob



More information about the busybox mailing list