[PATCH] device: increase object ref count before invoking g_idle_add



There are three different crash cases during the suspend&resume stress test.

Inreasing the object reference count before invoking g_idle_add() can avoid
this kind of race condition.

=== crash #1 ===
GNU gdb (Ubuntu 7.11-0ubuntu1) 7.11
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Reading symbols from /usr/sbin/NetworkManager...Reading symbols from 
/usr/lib/debug/.build-id/15/8d5eb163d8235942d8d39bf004fe114445ea7a.debug...done.
done.
[New LWP 878]
[New LWP 987]
[New LWP 989]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/sbin/NetworkManager --no-daemon'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  queued_ip6_config_change (user_data=0x24f7be0) at devices/nm-device.c:8913
8913            if (priv->queued_state.id)
[Current thread is 1 (Thread 0x7f819a689940 (LWP 878))]
(gdb) p priv
$1 = (NMDevicePrivate *) 0x440
(gdb) bt
#0  queued_ip6_config_change (user_data=0x24f7be0) at devices/nm-device.c:8913
#1  0x00007f819894bfda in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007f819894c380 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f819894c6a2 in g_main_loop_run () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x0000000000444d0a in main (argc=1, argv=0x7ffd7a962dc8) at main.c:477
(gdb) l
8908            NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8909            GSList *iter;
8910            gboolean need_ipv6ll = FALSE;
8911    
8912            /* Wait for any queued state changes */
8913            if (priv->queued_state.id)
8914                    return TRUE;
8915    
8916            priv->queued_ip6_config_id = 0;
8917            g_object_ref (self);

=== crash #2 ===
GNU gdb (Ubuntu 7.11-0ubuntu1) 7.11
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Reading symbols from /usr/sbin/NetworkManager...Reading symbols from 
/usr/lib/debug/.build-id/15/8d5eb163d8235942d8d39bf004fe114445ea7a.debug...done.
done.
[New LWP 776]
[New LWP 945]
[New LWP 943]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/sbin/NetworkManager --no-daemon'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f2c583f78f0 in g_type_check_instance_cast () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
[Current thread is 1 (Thread 0x7f2c59e39940 (LWP 776))]
(gdb) bt
#0  0x00007f2c583f78f0 in g_type_check_instance_cast () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#1  0x00000000004775d1 in queued_ip6_config_change (user_data=0x1fbe220) at devices/nm-device.c:8907
#2  0x00007f2c580fbfda in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f2c580fc380 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007f2c580fc6a2 in g_main_loop_run () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x0000000000444d0a in main (argc=1, argv=0x7fffe2cd4418) at main.c:477
(gdb) up 1
#1  0x00000000004775d1 in queued_ip6_config_change (user_data=0x1fbe220) at devices/nm-device.c:8907
8907            NMDevice *self = NM_DEVICE (user_data);
(gdb) p self
$1 = <optimized out>
(gdb) l
8902    }
8903    
8904    static gboolean
8905    queued_ip6_config_change (gpointer user_data)
8906    {
8907            NMDevice *self = NM_DEVICE (user_data);
8908            NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8909            GSList *iter;
8910            gboolean need_ipv6ll = FALSE;
8911    
(gdb) info registers
rax            0x1ee1220        32379424
rbx            0x1fbe220        33284640
rcx            0x0      0
rdx            0x1fbe220        33284640
rsi            0x1ee1220        32379424
rdi            0x1fbe220        33284640
rbp            0x4      0x4
rsp            0x7fffe2cd4130   0x7fffe2cd4130
r8             0x1f71cc0        32971968
r9             0x7f2c583c18e0   139828435622112
r10            0x7f2c57e8002f   139828430110767
r11            0x33     51
r12            0x1ebfad0        32242384
r13            0x1ed8db0        32345520
r14            0x1f910a0        33099936
r15            0x7f2c580f8a90   139828432702096
rip            0x4775d1 0x4775d1 <queued_ip6_config_change+33>
eflags         0x10202  [ IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) disassemble 
Dump of assembler code for function queued_ip6_config_change:
   0x00000000004775b0 <+0>:     push   %r15
   0x00000000004775b2 <+2>:     push   %r14
   0x00000000004775b4 <+4>:     push   %r13
   0x00000000004775b6 <+6>:     push   %r12
   0x00000000004775b8 <+8>:     push   %rbp
   0x00000000004775b9 <+9>:     push   %rbx
   0x00000000004775ba <+10>:    mov    %rdi,%rbx
   0x00000000004775bd <+13>:    sub    $0x8,%rsp
   0x00000000004775c1 <+17>:    callq  0x45fae0 <nm_device_get_type>
   0x00000000004775c6 <+22>:    mov    %rbx,%rdi
   0x00000000004775c9 <+25>:    mov    %rax,%rsi
   0x00000000004775cc <+28>:    callq  0x43fc60 <g_type_check_instance_cast plt>
=> 0x00000000004775d1 <+33>:    mov    0x20(%rax),%r12
   0x00000000004775d5 <+37>:    mov    0x1c(%r12),%edx
   0x00000000004775da <+42>:    test   %edx,%edx
   0x00000000004775dc <+44>:    je     0x4775f8 <queued_ip6_config_change+72>
...

=== crash #3 ===
GNU gdb (Ubuntu 7.11-0ubuntu1) 7.11
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Reading symbols from /usr/sbin/NetworkManager...Reading symbols from 
/usr/lib/debug/.build-id/15/8d5eb163d8235942d8d39bf004fe114445ea7a.debug...done.
done.
[New LWP 10856]
[New LWP 10857]
[New LWP 10859]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/sbin/NetworkManager --no-daemon'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f89ac67891b in g_type_check_instance_cast () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
[Current thread is 1 (Thread 0x7f89ae0ba940 (LWP 10856))]
(gdb) bt
#0  0x00007f89ac67891b in g_type_check_instance_cast () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#1  0x00000000004777f4 in queued_ip4_config_change (user_data=0xf56a90) at devices/nm-device.c:8887
#2  0x00007f89ac37cfda in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f89ac37d380 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007f89ac37d6a2 in g_main_loop_run () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x0000000000444d0a in main (argc=1, argv=0x7fff50540398) at main.c:477
(gdb) up 1
#1  0x00000000004777f4 in queued_ip4_config_change (user_data=0xf56a90) at devices/nm-device.c:8887
8887            NMDevice *self = NM_DEVICE (user_data);
(gdb) p self
$1 = <optimized out>
(gdb) info registers
rax            0xf34220 15942176
rbx            0xf56a90 16083600
rcx            0x0      0
rdx            0x2460   9312
rsi            0xf34220 15942176
rdi            0xf56a90 16083600
rbp            0x0      0x0
rsp            0x7fff505400e0   0x7fff505400e0
r8             0x180cebe00      6456000000
r9             0x7f89ac6428e0   140229279492320
r10            0xfe9e90 16686736
r11            0x202    514
r12            0xf12ad0 15805136
r13            0xf2bdb0 15908272
r14            0xf6f000 16183296
r15            0x7f89ac379a90   140229276572304
rip            0x4777f4 0x4777f4 <queued_ip4_config_change+20>
eflags         0x10206  [ PF IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) disassemble 
Dump of assembler code for function queued_ip4_config_change:
   0x00000000004777e0 <+0>:     push   %rbx
   0x00000000004777e1 <+1>:     mov    %rdi,%rbx
   0x00000000004777e4 <+4>:     callq  0x45fae0 <nm_device_get_type>
   0x00000000004777e9 <+9>:     mov    %rbx,%rdi
   0x00000000004777ec <+12>:    mov    %rax,%rsi
   0x00000000004777ef <+15>:    callq  0x43fc60 <g_type_check_instance_cast plt>
=> 0x00000000004777f4 <+20>:    mov    0x20(%rax),%rdx
   0x00000000004777f8 <+24>:    mov    0x1c(%rdx),%ecx
   0x00000000004777fb <+27>:    test   %ecx,%ecx
   0x00000000004777fd <+29>:    je     0x477810 <queued_ip4_config_change+48>
...

Shih-Yuan Lee (FourDollars) (1):
  device: increase object ref count before invoking g_idle_add

 src/devices/nm-device.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

-- 
2.7.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]