[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cairo
Subject:    Re: [cairo] Multi-threading issue
From:       Douwe Vos <dmvos2000 () yahoo ! com>
Date:       2017-10-02 19:24:06
Message-ID: 1794357859.2319534.1506972246266 () mail ! yahoo ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


So I was able to narrow down my crash Problem to the file cairo-ft-font.c. As far as \
I can see the lock_count on a cairo_ft_unscaled_font_t instance is protected by the \
mutex for that specific instance. At line 674 the lock_count is increased which is \
protected by the lock at line 673. When to many faces are open it tries to find faces \
where the lock_count is 0 at line 691 and then releases the face. Unfortunately this \
entry is not protected by the lock at line 673 (since this is another instance). So I \
added a lock on the returned entry at line 691 and recheck the value lock_count. \
Though this isn't optimal because there are now two locks, it did fix my crash \
problem. Below is the patch.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 3a4663d..8af6855 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -693,7 +693,12 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t \
*unscaled)  if (entry == NULL)
                               break;
  
-                     _font_map_release_face_lock_held (font_map, entry);
+                     CAIRO_MUTEX_LOCK (entry->mutex);
+                     if (_has_unlocked_face(entry))
+                     {
+                             _font_map_release_face_lock_held (font_map, entry);
+                     }
+                     CAIRO_MUTEX_UNLOCK (entry->mutex);
               }
         }
         _cairo_ft_unscaled_font_map_unlock ();

With regards,Douwe
 

    On Sunday, October 1, 2017, 12:16:47 AM GMT+2, Douwe Vos <dmvos2000@yahoo.com> \
wrote:    
 Hi I'm programming a text-editor called Natpad. For calculating the document \
width/height in pixels I use multiple threads. The document is split in multiple \
blocks where each block is handled in a separate request. Each request (which handles \
a block of the document) is calculating block dimensions using a new PangoContext \
created by invoking gtk_widget_create_pango_context. Once in a while it causes a \
Segmentation Fault (it is pretty consistent when opening a specific file). I've tried \
to find the cause of the problem and looked into pangofc-shape.c. It does call \
pango_fc_font_lock_face but still ft_face->size appears to be NULL at line 325. I've \
tried to add a very simple lock around the whole _pango_fc_shape function but this \
merely serialized all requests.  Any Ideas? Below is the stacktrace.

#0   0x00007ff4124d94b3 in _pango_fc_shape (font=0x7ff3c0199ae0, \
item_text=0x7ff3c030bea7 "͛,..)P.", item_length=2, analysis=0x7ff3d031ccd0, \
glyphs=0x27a5d40,   paragraph_text=0x7ff3c030be90 \
".S.ԁ\036/.\001\026B.o.ý\362\262\254\250ěa͛,..)P.", paragraph_length=31) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pangofc-shape.c:325 #1   \
0x00007ff415749918 in pango_shape_full (item_text=0x7ff3c030bea7 "͛,..)P.", \
item_length=2, paragraph_text=<optimized out>, paragraph_length=31, \
                analysis=0x7ff3d031ccd0, 
       glyphs=0x27a5d40) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/shape.c:116 #2   0x00007ff41573b6d1 in \
shape_run (line=line@entry=0x7ff3c0312630, state=state@entry=0x7ff3f67fb840, \
                item=item@entry=0x7ff3d031ccc0)
       at /build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:3296
#3   0x00007ff41573cf2c in process_item (layout=layout@entry=0x7ff3c8002210, \
line=line@entry=0x7ff3c0312630, state=state@entry=0x7ff3f67fb840, \
                force_fit=force_fit@entry=1, 
       no_break_at_end=no_break_at_end@entry=0) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:3409 #4   \
0x00007ff41573f4a4 in process_line (state=0x7ff3f67fb840, layout=0x7ff3c8002210) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:3708 #5   \
pango_layout_check_lines (layout=<optimized out>) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:4036 #6   \
0x00007ff4157411b8 in pango_layout_get_extents_internal (layout=0x7ff3c8002210, \
                ink_rect=0x0, logical_rect=0x7ff3f67fba90, line_extents=0x0)
       at /build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:2590
#7   0x00007ff4157416b6 in pango_layout_get_pixel_extents (layout=0x7ff3c8002210, \
                ink_rect=0x0, logical_rect=0x7ff3f67fba90)
       at /build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:2811
#8   0x00000000005930fa in cha_document_view_layout_page (document_view=0x28a5170, \
a_page=0x296aed0, page_layout_context=0x299dbf4, page_layout=0x29f8220, \
                test_for_concurrent_update=1)
       at /home/superman/cpp-workspace/natpad/chameleon/src/layout/chadocumentview.c:701
 #9   0x000000000059a20c in l_run_request (request=0x299dc40) at \
/home/superman/cpp-workspace/natpad/chameleon/src/layout/chapagelayoutrequest.c:199 \
#10 0x000000000063c498 in l_worker_run () #11 0x00007ff41496dbb5 in ?? () from \
/lib/x86_64-linux-gnu/libglib-2.0.so.0 #12 0x00007ff413e466ba in start_thread \
(arg=0x7ff3f67fc700) at pthread_create.c:333 #13 0x00007ff413b7c3dd in clone () at \
../sysdeps/unix/sysv/linux/x86_64/clone.S:109

To further analyze the Problem I've started compiling all involved libraries from \
source. After compiling it from source (using an alternative build system) the \
problem seemed to have disappeared (which doesn't really helped me finding the \
cause). I have now installed a separate environment and will start building the \
libraries using the default built system from Linux Mint. Once I succeed I will try \
to find out where the size is set to NULL.

Douwe Vos
  


[Attachment #5 (text/html)]

<html><head></head><body><div style="font-family:Helvetica Neue, Helvetica, Arial, \
sans-serif;font-size:13px;"><div>So I was able to narrow down my crash Problem to the \
file cairo-ft-font.c. As far as I can see the lock_count on a \
cairo_ft_unscaled_font_t instance is protected by the mutex for that specific \
instance. At line 674 the lock_count is increased which is protected by the lock at \
line 673. When to many faces are open it tries to find faces where the lock_count is \
0 at line 691 and then releases the face. Unfortunately this entry is not protected \
by the lock at line 673 (since this is another instance). So I added a lock on the \
returned entry at line 691 and recheck the value lock_count. Though this isn't \
optimal because there are now two locks, it did fix my crash problem. Below is the \
patch.<br></div><div><br></div><div>diff --git a/src/cairo-ft-font.c \
b/src/cairo-ft-font.c<br>index 3a4663d..8af6855 100644<br>--- \
a/src/cairo-ft-font.c<br>+++ b/src/cairo-ft-font.c<br>@@ -693,7 +693,12 @@ \
_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t \
*unscaled)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if \
(entry == NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
break;<br>&nbsp;<br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
_font_map_release_face_lock_held (font_map, \
entry);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
CAIRO_MUTEX_LOCK (entry-&gt;mutex);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
if (_has_unlocked_face(entry))<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
{<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
_font_map_release_face_lock_held (font_map, \
entry);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
}<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAIRO_MUTEX_UNLOCK \
(entry-&gt;mutex);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
}<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp; \
_cairo_ft_unscaled_font_map_unlock ();<br><br><div>With \
regards,</div><div>Douwe<br></div></div>  <div><br></div><div><br></div>
            
            <div id="ydp850a40d6yahoo_quoted_7006119145" \
                class="ydp850a40d6yahoo_quoted">
                <div style="font-family:'Helvetica Neue', Helvetica, Arial, \
sans-serif;font-size:13px;color:#26282a;">  
                    <div>
                        On Sunday, October 1, 2017, 12:16:47 AM GMT+2, Douwe Vos \
&lt;dmvos2000@yahoo.com&gt; wrote:  </div>
                    <div><br></div>
                    <div><br></div>
                    <div><div id="ydp850a40d6yiv1737006651"><div><div \
style="font-family:Helvetica Neue, Helvetica, Arial, \
sans-serif;font-size:13px;"><div>Hi I'm programming a text-editor called Natpad. For \
calculating the document width/height in pixels I use multiple threads. The document \
is split in multiple blocks where each block is handled in a separate request. Each \
request (which handles a block of the document) is calculating block dimensions using \
a new PangoContext created by invoking gtk_widget_create_pango_context. Once in a \
while it causes a Segmentation Fault (it is pretty consistent when opening a specific \
file). I've tried to find the cause of the problem and looked into pangofc-shape.c. \
It does call pango_fc_font_lock_face but still ft_face-&gt;size appears to be NULL at \
line 325. I've tried to add a very simple lock around the whole _pango_fc_shape \
function but this merely serialized all requests. </div><div><br></div><div>Any \
Ideas? Below is the stacktrace.<br></div><div><br></div><div>#0&nbsp; \
0x00007ff4124d94b3 in _pango_fc_shape (font=0x7ff3c0199ae0, item_text=0x7ff3c030bea7 \
"͛,..)P.", item_length=2, analysis=0x7ff3d031ccd0, glyphs=0x27a5d40, \
<br>&nbsp;&nbsp;&nbsp; paragraph_text=0x7ff3c030be90 \
".S.ԁ\036/.\001\026B.o.ý\362\262\254\250ěa͛,..)P.", paragraph_length=31) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pangofc-shape.c:325<br>#1&nbsp; \
0x00007ff415749918 in pango_shape_full (item_text=0x7ff3c030bea7 "͛,..)P.", \
item_length=2, paragraph_text=&lt;optimized out&gt;, paragraph_length=31, \
analysis=0x7ff3d031ccd0, <br>&nbsp;&nbsp;&nbsp; glyphs=0x27a5d40) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/shape.c:116<br>#2&nbsp; \
0x00007ff41573b6d1 in shape_run (line=line@entry=0x7ff3c0312630, \
state=state@entry=0x7ff3f67fb840, \
item=item@entry=0x7ff3d031ccc0)<br>&nbsp;&nbsp;&nbsp; at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:3296<br>#3&nbsp; \
0x00007ff41573cf2c in process_item (layout=layout@entry=0x7ff3c8002210, \
line=line@entry=0x7ff3c0312630, state=state@entry=0x7ff3f67fb840, \
force_fit=force_fit@entry=1, <br>&nbsp;&nbsp;&nbsp; \
no_break_at_end=no_break_at_end@entry=0) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:3409<br>#4&nbsp; \
0x00007ff41573f4a4 in process_line (state=0x7ff3f67fb840, layout=0x7ff3c8002210) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:3708<br>#5&nbsp; \
pango_layout_check_lines (layout=&lt;optimized out&gt;) at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:4036<br>#6&nbsp; \
0x00007ff4157411b8 in pango_layout_get_extents_internal (layout=0x7ff3c8002210, \
ink_rect=0x0, logical_rect=0x7ff3f67fba90, line_extents=0x0)<br>&nbsp;&nbsp;&nbsp; at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:2590<br>#7&nbsp; \
0x00007ff4157416b6 in pango_layout_get_pixel_extents (layout=0x7ff3c8002210, \
ink_rect=0x0, logical_rect=0x7ff3f67fba90)<br>&nbsp;&nbsp;&nbsp; at \
/build/pango1.0-EzEh0I/pango1.0-1.38.1/./pango/pango-layout.c:2811<br>#8&nbsp; \
0x00000000005930fa in cha_document_view_layout_page (document_view=0x28a5170, \
a_page=0x296aed0, page_layout_context=0x299dbf4, page_layout=0x29f8220, \
test_for_concurrent_update=1)<br>&nbsp;&nbsp;&nbsp; at \
/home/superman/cpp-workspace/natpad/chameleon/src/layout/chadocumentview.c:701<br>#9&nbsp; \
0x000000000059a20c in l_run_request (request=0x299dc40) at \
/home/superman/cpp-workspace/natpad/chameleon/src/layout/chapagelayoutrequest.c:199<br>#10 \
0x000000000063c498 in l_worker_run ()<br>#11 0x00007ff41496dbb5 in ?? () from \
/lib/x86_64-linux-gnu/libglib-2.0.so.0<br>#12 0x00007ff413e466ba in start_thread \
(arg=0x7ff3f67fc700) at pthread_create.c:333<br>#13 0x00007ff413b7c3dd in clone () at \
../sysdeps/unix/sysv/linux/x86_64/clone.S:109<br><br><div>To further analyze the \
Problem I've started compiling all involved  libraries from source. After compiling \
it from source (using an  alternative build system) the problem seemed to have \
disappeared (which  doesn't really helped me finding the cause). I have now installed \
a  separate environment and will start building the libraries using the 
default built system from Linux Mint. Once I succeed I will try to find out where the \
size is set to NULL.<br></div><div><br></div><div>Douwe \
Vos<br></div></div></div></div></div></div>  </div>
            </div></div></body></html>


[Attachment #6 (text/plain)]

-- 
cairo mailing list
cairo@cairographics.org
https://lists.cairographics.org/mailman/listinfo/cairo

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic