Skip to content

Instantly share code, notes, and snippets.

@mgedmin
Last active August 29, 2015 14:08
Show Gist options
  • Save mgedmin/3a01f7ac2f16d178d674 to your computer and use it in GitHub Desktop.
Save mgedmin/3a01f7ac2f16d178d674 to your computer and use it in GitHub Desktop.
Debug session of the overlay-scrollbars bug with Gtk+ 3.14
<mgedmin> I'm seeing very weird segfaults in glib
in g_closure_invoke(), to be precise
this is on ubuntu gnome 14.10 with their gnome3-staging ppa enabled, so who knows what got broken where
but basically all the apps are segfaulting left and right when widgets lose focus
the stack trace is this: https://gist.github.com/0c80f6e81d9dfc4a4fd7
I have a core dump and I can poke around it with gdb
and gdb tells me closure->marshal is 0x7fd4ba283040 <g_cclosure_marshal_VOID__BOOLEAN>
and real_closure->meta_marshal is 0x7fd4ba27fb10 <g_type_class_meta_marshal>
the segfault is here: https://github.com/GNOME/glib/blob/glib-2-42/gobject/gclosure.c#L768
it's invoking a local variable 'marshal' which is "optimized out" in the stack trace's locals
but disassembly tells me its value is kept in %rax
gdb tells me $rax is 0
this shouldn't be possible
so... compiler bug?
inline assembly that clobbers %rax without telling gcc about it?
glib is ubuntu-gnome's, not overridden by the ppa
but segfaults only show up when the ppa is added to the system
Dump of assembler code for function g_closure_invoke:
0x00007fd4ba281100 <+0>: test %rdi,%rdi
0x00007fd4ba281103 <+3>: je 0x7fd4ba2811f0 <g_closure_invoke+240>
JUMP NOT TAKEN
0x00007fd4ba281109 <+9>: push %r15
0x00007fd4ba28110b <+11>: push %r14
0x00007fd4ba28110d <+13>: mov %r8,%r15
0x00007fd4ba281110 <+16>: push %r13
0x00007fd4ba281112 <+18>: push %r12
0x00007fd4ba281114 <+20>: mov %rcx,%r14
0x00007fd4ba281117 <+23>: push %rbp
0x00007fd4ba281118 <+24>: push %rbx
0x00007fd4ba281119 <+25>: mov %rdi,%rbx
0x00007fd4ba28111c <+28>: mov %edx,%r13d
0x00007fd4ba28111f <+31>: mov %rsi,%r12
0x00007fd4ba281122 <+34>: sub $0x38,%rsp
0x00007fd4ba281126 <+38>: callq 0x7fd4ba280930 <g_closure_ref>
0x00007fd4ba28112b <+43>: mov (%rbx),%rax
0x00007fd4ba28112e <+46>: test $0x80000000,%eax
0x00007fd4ba281133 <+51>: jne 0x7fd4ba2811da <g_closure_invoke+218>
0x00007fd4ba281139 <+57>: mov (%rbx),%rbp
0x00007fd4ba28113c <+60>: shr $0x1e,%rbp
0x00007fd4ba281140 <+64>: and $0x1,%ebp
0x00007fd4ba281143 <+67>: cmpq $0x0,0x8(%rbx)
0x00007fd4ba281148 <+72>: je 0x7fd4ba281272 <g_closure_invoke+370>
JUMP NOT TAKEN
0x00007fd4ba28114e <+78>: xchg %ax,%ax
LOOP HERE FROM +118
JUMP HERE FROM +357
0x00007fd4ba281150 <+80>: mov (%rbx),%eax
0x00007fd4ba281152 <+82>: mov %eax,0x10(%rsp)
0x00007fd4ba281156 <+86>: mov 0x10(%rsp),%rdx
0x00007fd4ba28115b <+91>: mov 0x10(%rsp),%edx
0x00007fd4ba28115f <+95>: or $0x40000000,%edx
0x00007fd4ba281165 <+101>: mov %edx,0x10(%rsp)
0x00007fd4ba281169 <+105>: mov 0x10(%rsp),%rdx
0x00007fd4ba28116e <+110>: mov 0x10(%rsp),%edx
0x00007fd4ba281172 <+114>: lock cmpxchg %edx,(%rbx)
0x00007fd4ba281176 <+118>: jne 0x7fd4ba281150 <g_closure_invoke+80>
0x00007fd4ba281178 <+120>: mov -0x20(%rbx),%rax
GDB TELLS ME THIS IS real_closure->meta_marshal, which is not 0 (it's 0x7fd4ba27fb10)
0x00007fd4ba28117c <+124>: test %rax,%rax
0x00007fd4ba28117f <+127>: je 0x7fd4ba281266 <g_closure_invoke+358>
JUMP TAKEN, I"M SURE
IF NOT, THEN %rax is not 0 here, BUT THIS FALLS THROUGH AND WE GO TO +266 WHERE %rax IS 0
0x00007fd4ba281185 <+133>: mov -0x18(%rbx),%r9
JUMP HERE FROM +365
0x00007fd4ba281189 <+137>: test %bpl,%bpl
0x00007fd4ba28118c <+140>: je 0x7fd4ba28120a <g_closure_invoke+266>
JUMP TAKEN, VALUE OF %rax IS FINAL
0x00007fd4ba28118e <+142>: mov %r15,%r8
0x00007fd4ba281191 <+145>: mov %r14,%rcx
0x00007fd4ba281194 <+148>: mov %r13d,%edx
0x00007fd4ba281197 <+151>: mov %r12,%rsi
0x00007fd4ba28119a <+154>: mov %rbx,%rdi
0x00007fd4ba28119d <+157>: callq *%rax
JUMP HERE FROM +333, +353:
0x00007fd4ba28119f <+159>: mov %ebp,%ecx
0x00007fd4ba2811a1 <+161>: and $0x1,%ecx
0x00007fd4ba2811a4 <+164>: shl $0x1e,%ecx
0x00007fd4ba2811a7 <+167>: nopw 0x0(%rax,%rax,1)
LOOP HERE FROM +216:
0x00007fd4ba2811b0 <+176>: mov (%rbx),%eax
0x00007fd4ba2811b2 <+178>: mov %eax,0x10(%rsp)
0x00007fd4ba2811b6 <+182>: mov 0x10(%rsp),%rdx
0x00007fd4ba2811bb <+187>: mov 0x10(%rsp),%edx
0x00007fd4ba2811bf <+191>: and $0xbfffffff,%edx
0x00007fd4ba2811c5 <+197>: or %ecx,%edx
0x00007fd4ba2811c7 <+199>: mov %edx,0x10(%rsp)
0x00007fd4ba2811cb <+203>: mov 0x10(%rsp),%rdx
0x00007fd4ba2811d0 <+208>: mov 0x10(%rsp),%edx
0x00007fd4ba2811d4 <+212>: lock cmpxchg %edx,(%rbx)
0x00007fd4ba2811d8 <+216>: jne 0x7fd4ba2811b0 <g_closure_invoke+176>
JUMP HERE FROM +51:
0x00007fd4ba2811da <+218>: add $0x38,%rsp
0x00007fd4ba2811de <+222>: mov %rbx,%rdi
0x00007fd4ba2811e1 <+225>: pop %rbx
0x00007fd4ba2811e2 <+226>: pop %rbp
0x00007fd4ba2811e3 <+227>: pop %r12
0x00007fd4ba2811e5 <+229>: pop %r13
0x00007fd4ba2811e7 <+231>: pop %r14
0x00007fd4ba2811e9 <+233>: pop %r15
0x00007fd4ba2811eb <+235>: jmpq 0x7fd4ba280a30 <g_closure_unref>
------------------------------------------
JUMP HERE FROM +3:
0x00007fd4ba2811f0 <+240>: lea 0x30a75(%rip),%rdx # 0x7fd4ba2b1c6c
0x00007fd4ba2811f7 <+247>: lea 0x2bed2(%rip),%rsi # 0x7fd4ba2ad0d0 <__FUNCTION__.12219>
0x00007fd4ba2811fe <+254>: lea 0x2a5c9(%rip),%rdi # 0x7fd4ba2ab7ce
0x00007fd4ba281205 <+261>: jmpq 0x7fd4ba27be90 <g_return_if_fail_warning@plt>
------------------------------------------
JUMP HERE FROM +140
0x00007fd4ba28120a <+266>: mov (%rbx),%rdx
GDB TELLS ME THIS IS 0x40000002
0x00007fd4ba28120d <+269>: test $0x10000,%edx
0x00007fd4ba281213 <+275>: je 0x7fd4ba281234 <g_closure_invoke+308>
DOES NOT MATTER IF JUMP TAKEN, %rax IS UNCHANGED IN EITHER BRANCH
0x00007fd4ba281215 <+277>: mov 0x18(%rbx),%rdx
0x00007fd4ba281219 <+281>: mov %r9,0x8(%rsp)
0x00007fd4ba28121e <+286>: mov %rbx,%rsi
0x00007fd4ba281221 <+289>: mov %rax,(%rsp)
0x00007fd4ba281225 <+293>: mov (%rdx),%rdi
0x00007fd4ba281228 <+296>: callq *0x8(%rdx)
0x00007fd4ba28122b <+299>: mov (%rsp),%rax
0x00007fd4ba28122f <+303>: mov 0x8(%rsp),%r9
JUMP HERE from +275
0x00007fd4ba281234 <+308>: mov %r15,%r8
0x00007fd4ba281237 <+311>: mov %r14,%rcx
0x00007fd4ba28123a <+314>: mov %r13d,%edx
0x00007fd4ba28123d <+317>: mov %r12,%rsi
0x00007fd4ba281240 <+320>: mov %rbx,%rdi
0x00007fd4ba281243 <+323>: callq *%rax
CRASH: at this point %rax is 0
=> 0x00007fd4ba281245 <+325>: mov (%rbx),%rax
0x00007fd4ba281248 <+328>: test $0x10000,%eax
0x00007fd4ba28124d <+333>: je 0x7fd4ba28119f <g_closure_invoke+159>
0x00007fd4ba281253 <+339>: mov 0x18(%rbx),%rax
0x00007fd4ba281257 <+343>: mov %rbx,%rsi
0x00007fd4ba28125a <+346>: mov 0x10(%rax),%rdi
0x00007fd4ba28125e <+350>: callq *0x18(%rax)
0x00007fd4ba281261 <+353>: jmpq 0x7fd4ba28119f <g_closure_invoke+159>
------------------------------------------
JUMP HERE FROM +127
0x00007fd4ba281266 <+358>: mov 0x8(%rbx),%rax
GDB TELLS ME THIS IS closure->marshal WHICH IS NOT 0, IT's 0x7fd4ba283040
0x00007fd4ba28126a <+362>: xor %r9d,%r9d
0x00007fd4ba28126d <+365>: jmpq 0x7fd4ba281189 <g_closure_invoke+137>
------------------------------------------
JUMP HERE FROM +72
0x00007fd4ba281272 <+370>: cmpq $0x0,-0x20(%rbx)
0x00007fd4ba281277 <+375>: jne 0x7fd4ba281150 <g_closure_invoke+80>
0x00007fd4ba28127d <+381>: add $0x38,%rsp
0x00007fd4ba281281 <+385>: lea 0x2b720(%rip),%rdx # 0x7fd4ba2ac9a8
0x00007fd4ba281288 <+392>: lea 0x2be41(%rip),%rsi # 0x7fd4ba2ad0d0 <__FUNCTION__.12219>
0x00007fd4ba28128f <+399>: pop %rbx
0x00007fd4ba281290 <+400>: pop %rbp
0x00007fd4ba281291 <+401>: pop %r12
0x00007fd4ba281293 <+403>: pop %r13
0x00007fd4ba281295 <+405>: pop %r14
0x00007fd4ba281297 <+407>: pop %r15
0x00007fd4ba281299 <+409>: lea 0x2a52e(%rip),%rdi # 0x7fd4ba2ab7ce
0x00007fd4ba2812a0 <+416>: jmpq 0x7fd4ba27be90 <g_return_if_fail_warning@plt>
------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment