Patchwork monitor: fix crash at info pci

login
register
mail settings
Submitter Michael S. Tsirkin
Date Feb. 1, 2010, 3:12 p.m.
Message ID <20100201151210.GA9453@redhat.com>
Download mbox | patch
Permalink /patch/44206/
State New
Headers show

Comments

Michael S. Tsirkin - Feb. 1, 2010, 3:12 p.m.
info pci returns a bus object, not a qdict, which leads to a crash in
monitor which wants a qdict.  Not sure what the right fix is: this patch
just checks and handles non-disct command as synchronous.  OTOH if we
definitely need all commands to return a dict, we should change return
type appropriately.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

I got a crash at info pci command which looked
like this:

(qemu) info pci
  Bus  0, device   0, function 0:
    Host bridge: PCI device 8086:1237
      id ""                          
  Bus  0, device   1, function 0:    
    ISA bridge: PCI device 8086:7000 
      id ""                          
  Bus  0, device   1, function 1:    
    IDE controller: PCI device 8086:7010
      BAR4: I/O at 0xc000 [0xc00f].     
      id ""                             
  Bus  0, device   1, function 3:       
    Bridge: PCI device 8086:7113        
      IRQ 9.                            
      id ""                             
  Bus  0, device   2, function 0:       
    VGA controller: PCI device 1013:00b8
      BAR0: 32 bit prefetchable memory at 0xe0000000 [0xe1ffffff].
      BAR1: 32 bit memory at 0xe2000000 [0xe2000fff].             
      BAR6: 32 bit memory at 0xffffffffffffffff [0x0000fffe].     
      id ""                                                       
  Bus  0, device   3, function 0:                                 
    Ethernet controller: PCI device 8086:100e                     
      IRQ 11.                                                     
      BAR0: 32 bit memory at 0xe2020000 [0xe203ffff].             
      BAR1: I/O at 0xc040 [0xc07f].                               
      BAR6: 32 bit memory at 0xffffffffffffffff [0x0001fffe].     
      id ""                                                       
  Bus  0, device   4, function 0:                                 
    Ethernet controller: PCI device 1af4:1000                     
      IRQ 11.                                                     
      BAR0: I/O at 0xc080 [0xc09f].                               
      BAR1: 32 bit memory at 0xe2060000 [0xe2060fff].             
      BAR6: 32 bit memory at 0xffffffffffffffff [0x0000fffe].     
      id ""                                                       

Program received signal SIGSEGV, Segmentation fault.
qdict_find (qdict=0x0, key=0x5a382a "__mon_async", hash=<value optimized out>) at qdict.c:92
92          QLIST_FOREACH(entry, &qdict->table[hash], next)                                 
(gdb) p qdict->table[hash]
Cannot access memory at address 0x18
(gdb) where                         
#0  qdict_find (qdict=0x0, key=0x5a382a "__mon_async", hash=<value optimized out>) at qdict.c:92
#1  0x000000000045d25e in qdict_haskey (qdict=0x0, key=0x5a382a "__mon_async") at qdict.c:151   
#2  0x00000000004153ec in is_async_return (data=<value optimized out>) at /root/scm/qemu/monitor.c:3703
#3  monitor_call_handler (data=<value optimized out>) at /root/scm/qemu/monitor.c:3713                 
#4  0x0000000000417510 in handle_user_command (mon=0xcf3010, cmdline=0x5a6530 "")                      
    at /root/scm/qemu/monitor.c:3749                                                                   
#5  0x00000000004176de in monitor_command_cb (mon=0xcf3010, cmdline=<value optimized out>,             
    opaque=<value optimized out>) at /root/scm/qemu/monitor.c:4263                                     
#6  0x000000000046169b in readline_handle_byte (rs=0x12080b0, ch=<value optimized out>) at readline.c:369
#7  0x000000000041776c in monitor_read (opaque=<value optimized out>, buf=0x7fffffffcc60 "\r\212\204$\245", 
    size=1) at /root/scm/qemu/monitor.c:4249                                                                
#8  0x00000000004824eb in fd_chr_read (opaque=0xc8ab70) at qemu-char.c:568                                  
#9  0x000000000040aa90 in main_loop_wait (timeout=5000) at /root/scm/qemu/vl.c:3758                         
#10 0x000000000040d015 in main_loop () at /root/scm/qemu/vl.c:3981                                          
#11 main () at /root/scm/qemu/vl.c:6027                                                                     
(gdb) frame 3                                                                                               
#3  monitor_call_handler (data=<value optimized out>) at /root/scm/qemu/monitor.c:3713                      
3713        if (is_async_return(data)) {                                                                    
(gdb) p data                                                                                                
$1 = (QObject *) 0xc89fc0                                                                                   
(gdb) p *data                                                                                               
$2 = {type = 0x5d0a10, refcnt = 1}                                                                          

this seems to fix it.
Michael S. Tsirkin - Feb. 1, 2010, 4:11 p.m.
On Mon, Feb 01, 2010 at 01:19:50PM -0200, Luiz Capitulino wrote:
> On Mon, 1 Feb 2010 17:12:11 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > info pci returns a bus object, not a qdict, which leads to a crash in
> > monitor which wants a qdict.  Not sure what the right fix is: this patch
> > just checks and handles non-disct command as synchronous.  OTOH if we
> > definitely need all commands to return a dict, we should change return
> > type appropriately.
> 
>  This has already been fixed by commit 82617d7, thanks anyway :)

Yes, fixed now.

Patch

diff --git a/monitor.c b/monitor.c
index fbae5ce..b681c53 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3700,7 +3700,8 @@  static void monitor_print_error(Monitor *mon)
 
 static int is_async_return(const QObject *data)
 {
-    return data && qdict_haskey(qobject_to_qdict(data), "__mon_async");
+    return data && qobject_to_qdict(data) &&
+	    qdict_haskey(qobject_to_qdict(data), "__mon_async");
 }
 
 static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd,