def-/xdot

cairoContextGetFontOptions call leads to segfault on macOS

Closed this issue · 4 comments

rcook commented

I've been working on getting this package working on macOS and I'm stuck on one last thing. The call to cairoContextGetFontOptions (here) leads to a segfault:

Process:               xdot-demo [19171]
Path:                  /Users/USER/*/xdot-demo
Identifier:            xdot-demo
Version:               0
Code Type:             X86-64 (Native)
Parent Process:        ??? [19127]
Responsible:           xdot-demo [19171]
User ID:               2111029715

Date/Time:             2018-11-06 11:08:57.741 -0800
OS Version:            Mac OS X 10.12.6 (16G1618)
Report Version:        12
Anonymous UUID:        6D759AC0-233D-C786-DD53-F5FCA442D89D

Sleep/Wake UUID:       E225E286-E598-4E23-BD52-B4AC6B386FF8

Time Awake Since Boot: 4200 seconds
Time Since Wake:       3100 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Application Specific Information:
abort() called
*** error for object 0x2000000000000: pointer being freed was not allocated
 

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib        	0x00007fffbb6bcd42 __pthread_kill + 10
1   libsystem_pthread.dylib       	0x00007fffbb7aa457 pthread_kill + 90
2   libsystem_c.dylib             	0x00007fffbb622420 abort + 129
3   libsystem_malloc.dylib        	0x00007fffbb711fe7 free + 530
4   libcairo.2.dylib              	0x000000010679b8bc cairo_font_options_destroy + 35
5   libpangocairo-1.0.0.dylib     	0x0000000106705d12 free_context_info + 23
6   libglib-2.0.0.dylib           	0x0000000106a578d0 g_datalist_clear + 114
7   libgobject-2.0.0.dylib        	0x0000000106a0abe5 g_object_unref + 346
8   libpango-1.0.0.dylib          	0x00000001067318b5 pango_layout_finalize + 28
9   libgobject-2.0.0.dylib        	0x0000000106a0abe5 g_object_unref + 346
10  xdot-demo                     	0x0000000104aeb0c2 0x104974000 + 1536194

Thread 1:
0   libsystem_pthread.dylib       	0x00007fffbb7a7070 start_wqthread + 0
1   ???                           	0x0000000000000007 0 + 7

Thread 2:
0   libsystem_pthread.dylib       	0x00007fffbb7a7070 start_wqthread + 0
1   ???                           	0x00007f982608ffff 0 + 140291449880575

Thread 3:
0   libsystem_pthread.dylib       	0x00007fffbb7a7070 start_wqthread + 0
1   ???                           	0x0000003c0000f000 0 + 257698099200

Thread 4:
0   libsystem_pthread.dylib       	0x00007fffbb7a7070 start_wqthread + 0
1   ???                           	0x0000000000000001 0 + 1

Thread 5:
0   libsystem_kernel.dylib        	0x00007fffbb6bceb6 __select + 10
1   libglib-2.0.0.dylib           	0x0000000106a7e390 g_poll + 430
2   libgdk-3.0.dylib              	0x00000001066a936c select_thread_func + 113
3   libsystem_pthread.dylib       	0x00007fffbb7a793b _pthread_body + 180
4   libsystem_pthread.dylib       	0x00007fffbb7a7887 _pthread_start + 286
5   libsystem_pthread.dylib       	0x00007fffbb7a708d thread_start + 13

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x0000000000000006  rcx: 0x00007fff5b27f858  rdx: 0x0000000000000000
  rdi: 0x0000000000000307  rsi: 0x0000000000000006  rbp: 0x00007fff5b27f880  rsp: 0x00007fff5b27f858
   r8: 0x0000000000000000   r9: 0x0000000000000000  r10: 0x0000000008000000  r11: 0x0000000000000206
  r12: 0x0000000000000004  r13: 0x0000000000000004  r14: 0x00007fffc44a93c0  r15: 0x0000000000000000
  rip: 0x00007fffbb6bcd42  rfl: 0x0000000000000206  cr2: 0x00007fffc448b128

I've isolated it to this one offending section of the code. If I remove this line of code and everything else that depends on its result (here), the XDot demo runs without crashing.

def- commented

Great to see someone caring about this package. Is fo maybe returning a nullpointer and should we check for that?

rcook commented

My guess is that pango_cairo_context_get_font_options is internally returning a null pointer before cairoContextGetFontOptions is about to return to the XDot code, so I'm not sure how we'd check for null. It's possible that the cairoContextGetFontOptions implementation is the problem. References:

https://github.com/gtk2hs/gtk2hs/blob/d3d62fbd9460f23559a9ca44637480b9cc773e43/pango/Graphics/Rendering/Pango/Cairo.chs#L176

https://github.com/gtk2hs/gtk2hs/blob/f91ba9ddaf27be7aedce91d2f6d459f294c83859/cairo/Graphics/Rendering/Cairo/Types.chs#L337

This might be a bug in gtk2hs or a combination of gtk2hs and XDot.

rcook commented

I've developed one possible workaround: rcook@b373370

The "proper" fix, as suggested in the comment, would be for gtk2hs to not segfault if pango_cairo_context_get_font_options returns null (I think).

I'll investigate some more and possibly open an issue against gtk2hs.