public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: Lynn Kerby <lfk@kerbit.net>
Cc: kvm@vger.kernel.org, Marcelo Tosatti <mtosatti@redhat.com>
Subject: Re: [kvm-devel] VNC segfault
Date: Mon, 19 May 2008 18:42:19 -0500	[thread overview]
Message-ID: <4832105B.3020707@codemonkey.ws> (raw)
In-Reply-To: <CD663C99-C230-44CC-81A9-C3A648EA0940@kerbit.net>

Lynn Kerby wrote:
>
> On May 17, 2008, at 2:55 PM, Anthony Liguori wrote:
>
>> Marcelo Tosatti wrote:
>>> Hi Anthony,
>>>
>>> We're experiencing qemu segfaults when using VNC over high latency
>>> links.
>>>
>>> (gdb) bt
>>> #0  0x0000003a8ec838d3 in memcpy () from /lib64/libc.so.6
>>> #1  0x00000000004b9aff in vnc_update_client (opaque=0x3514140) at 
>>> vnc.c:223
>>> #2  0x000000000040822d in qemu_run_timers (ptimer_head=0x8e9500, 
>>> current_time=5942450)
>>>     at /root/marcelo/kvm-userspace/qemu/vl.c:1112
>>> #3  0x0000000000413208 in main_loop_wait (timeout=1000)
>>>     at /root/marcelo/kvm-userspace/qemu/vl.c:7482
>>> #4  0x000000000060de86 in kvm_main_loop ()
>>>     at /root/marcelo/kvm-userspace/qemu/qemu-kvm.c:524
>>> #5  0x0000000000413259 in main_loop () at 
>>> /root/marcelo/kvm-userspace/qemu/vl.c:7506
>>> #6  0x0000000000415d3a in main (argc=21, argv=0x7fff00907dd8)
>>>     at /root/marcelo/kvm-userspace/qemu/vl.c:9369
>>>
>>> Problem is that sometimes vs->width and vs->weight are not updated to
>>> reflect the size allocated for the display memory. If they are larger
>>> than whats allocated it segfaults:
>>>
>>> (gdb) p vs->old_data_h
>>> $22 = 400
>>> (gdb) p vs->old_data_w
>>> $23 = 720
>>> (gdb) p vs->old_data_depth
>>> $24 = 4
>>>
>>> (gdb) p vs->height
>>> $20 = 480
>>> (gdb) p vs->width
>>> $21 = 640
>>> (gdb) p vs->depth
>>> $25 = 4
>>>
>>> old_data_h, old_data_w and old_data_depth have been saved from the last
>>> vnc_dpy_resize run. The code relies on the client's "set_encondings"
>>> processing to happen _before_ the vnc_update_client() timer triggers,
>>> which might not always be the case.
>>>
>>> I have no clue about correctness of the following though. What do you
>>> say?
>>>
>>
>> The patch isn't right because it will unconditionally send DesktopResize
>> updates even with clients that don't support it.  It happens to work for
>> you because your client ignores it and there's no data associated with
>> DesktopResize.  A client really should just stop though.
>>
>> vs->{width,height} are supposed to correspond to the client's buffer.
>> In the absence of DesktopResize, the client's buffer stays fixed.
>>
>> I think what's probably needed is some checks vnc_dpy_update() to not
>> exceed the dimensions of vs->{width,height}.  Something like the 
>> following:
>>
>> diff --git a/vnc.c b/vnc.c
>> index 842124b..4b57838 100644
>> --- a/vnc.c
>> +++ b/vnc.c
>> @@ -265,6 +265,11 @@ static void vnc_dpy_update(DisplayState *ds, int x,
>> int y,
>>     w += (x % 16);
>>     x -= (x % 16);
>>
>> +    x = MIN(x, vs->width);
>> +    y = MIN(y, vs->height);
>> +    w = MIN(x + w, vs->width) - x;
>> +    h = MIN(y + h, vs->height) - y;
>> +
>>     for (; y < h; y++)
>>        for (i = 0; i < w; i += 16)
>>            vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
>>
>> Regards,
>>
>> Anthony Liguori
>
> This doesn't work right for me.
>
> Based on my observations the setting of w and h are causing the 
> display updates to not occur in the lower portion of the VNC screen.  
> I discovered this because my mouse pointer stopped before hitting the 
> bottom of  the screen which made installation of RedHat EL 5 nearly 
> impossible to complete.   The following patch just limits w and h to 
> the max width and it works *much* better but still seems like a hack 
> instead of a real fix.  The incorrect x and y values could still be 
> used by this function to modify w and h.
>
>> --- qemu/vnc.c.orig    2008-05-12 04:30:43.000000000 -0700
>> +++ qemu/vnc.c    2008-05-19 15:55:47.000000000 -0700
>> @@ -265,6 +265,11 @@ static void vnc_dpy_update(DisplayState
>>      w += (x % 16);
>>      x -= (x % 16);
>>
>> +    x = MIN(x, vs->width);
>> +    y = MIN(y, vs->height);
>> +    w = MIN(w, vs->width);
>> +    h = MIN(h, vs->height);
>> +
>>      for (; y < h; y++)
>>      for (i = 0; i < w; i += 16)
>>          vnc_set_bit(vs->dirty_row[y], (x + i) / 16);

Strange, your patch can still result in a region that is too large (if x 
== vs->width for instance).

Can you add some debugging to see if your patch ever results in a 
smaller region than my patch?

Regards,

Anthony Liguori

> Lynn Kerby
>


      reply	other threads:[~2008-05-19 23:42 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-16 21:39 VNC segfault Marcelo Tosatti
     [not found] ` <482F543C.1070901@codemonkey.ws>
2008-05-19 23:31   ` [kvm-devel] " Lynn Kerby
2008-05-19 23:42     ` Anthony Liguori [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4832105B.3020707@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=kvm@vger.kernel.org \
    --cc=lfk@kerbit.net \
    --cc=mtosatti@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox