Bug in GC's ordering of ForeignPtr finalization?
[notmuch-archives.git] / 44 / 5cb3dcab2616fa4bb764dd86344678e182b39e
1 Return-Path: <bgamari.foss@gmail.com>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 169EA429E25\r
6         for <notmuch@notmuchmail.org>; Sun, 28 Aug 2011 14:27:57 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.799\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.799 tagged_above=-999 required=5\r
12         tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
13         FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
14 Received: from olra.theworths.org ([127.0.0.1])\r
15         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
16         with ESMTP id mBcdffUtvCiR for <notmuch@notmuchmail.org>;\r
17         Sun, 28 Aug 2011 14:27:56 -0700 (PDT)\r
18 Received: from mail-qy0-f174.google.com (mail-qy0-f174.google.com\r
19         [209.85.216.174]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
20         (No client certificate requested)\r
21         by olra.theworths.org (Postfix) with ESMTPS id 66546431FB6\r
22         for <notmuch@notmuchmail.org>; Sun, 28 Aug 2011 14:27:56 -0700 (PDT)\r
23 Received: by qyk15 with SMTP id 15so524440qyk.5\r
24         for <notmuch@notmuchmail.org>; Sun, 28 Aug 2011 14:27:54 -0700 (PDT)\r
25 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\r
26         h=from:to:cc:subject:in-reply-to:references:user-agent:date\r
27         :message-id:mime-version:content-type;\r
28         bh=sOjh0HDAk6mwLBOH/i3AU5PBlVyB1xjPpDiXlchbDQs=;\r
29         b=XoPOyY4+D3hu/NRIPa2NLyC41zGulmrCQO2rUYx5hmsSWhVH8tHs8zh2nRhkNOJPlU\r
30         lrPg5HW0x9nrOtU4qaIe1ezTth6lrBGxmk8TbLCKmywrmnsO4xF7Ezl/3tXWcYPFFvft\r
31         BaRAifb8V/WHUVpGWW8qU3U2zOyFttEvzSPDI=\r
32 Received: by 10.229.67.220 with SMTP id s28mr4830435qci.270.1314566873903;\r
33         Sun, 28 Aug 2011 14:27:53 -0700 (PDT)\r
34 Received: from localhost (pool-96-240-192-157.spfdma.east.verizon.net\r
35         [96.240.192.157])\r
36         by mx.google.com with ESMTPS id m11sm2999795qcw.43.2011.08.28.14.27.52\r
37         (version=TLSv1/SSLv3 cipher=OTHER);\r
38         Sun, 28 Aug 2011 14:27:52 -0700 (PDT)\r
39 From: Ben Gamari <bgamari.foss@gmail.com>\r
40 To: Bart Massey <bart@cs.pdx.edu>, haskell-cafe@haskell.org,\r
41         glasgow-haskell-users@haskell.org\r
42 Subject: Bug in GC's ordering of ForeignPtr finalization?\r
43 In-Reply-To: <8739h1pbaq.fsf@gmail.com>\r
44 References: <8739h1pbaq.fsf@gmail.com>\r
45 User-Agent: Notmuch/0.6.1-76-g1635f57 (http://notmuchmail.org) Emacs/23.2.1\r
46         (x86_64-pc-linux-gnu)\r
47 Date: Sun, 28 Aug 2011 17:27:49 -0400\r
48 Message-ID: <87pqjprzu2.fsf@gmail.com>\r
49 MIME-Version: 1.0\r
50 Content-Type: text/plain; charset=us-ascii\r
51 Cc: notmuch@notmuchmail.org\r
52 X-BeenThere: notmuch@notmuchmail.org\r
53 X-Mailman-Version: 2.1.13\r
54 Precedence: list\r
55 List-Id: "Use and development of the notmuch mail system."\r
56         <notmuch.notmuchmail.org>\r
57 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
58         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
59 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
60 List-Post: <mailto:notmuch@notmuchmail.org>\r
61 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
62 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
63         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
64 X-List-Received-Date: Sun, 28 Aug 2011 21:27:57 -0000\r
65 \r
66 On Tue, 16 Aug 2011 12:32:13 -0400, Ben Gamari <bgamari.foss@gmail.com> wrote:\r
67 > It seems that the notmuch-haskell bindings (version 0.2.2 built against\r
68 > notmuch from git master; passes notmuch-test) aren't dealing with memory\r
69 > management properly. In particular, the attached test code[1] causes\r
70 > talloc to abort.  Unfortunately, while the issue is consistently\r
71 > reproducible, it only occurs with some queries (see source[1]). I have\r
72 > been unable to establish the exact criterion for failure.\r
73\r
74 > It seems that the crash is caused by an invalid access to a freed Query\r
75 > object while freeing a Messages object (see Valgrind trace[3]). I've\r
76 > taken a brief look at the bindings themselves but, being only minimally\r
77 > familiar with the FFI, there's nothing obviously wrong (the finalizers\r
78 > passed to newForeignPtr look sane). I was under the impression that\r
79 > talloc was reference counted, so the Query object shouldn't have been\r
80 > freed unless if there was still a Messages object holding a\r
81 > reference. Any idea what might have gone wrong here?  Thanks!\r
82\r
83 After looking into this issue in a bit more depth, I'm even more\r
84 confused. In fact, I would not be surprised if I have stumbled into a\r
85 bug in the GC. It seems that the notmuch-haskell bindings follow the\r
86 example of the python bindings in that child objects keep references to\r
87 their parents to prevent the garbage collector from releasing the\r
88 parent, which would in turn cause talloc to free the child objects,\r
89 resulting in odd behavior when the child objects were next accessed. For\r
90 instance, the Query and Messages objects are defined as follows,\r
91 \r
92     type MessagesPtr = ForeignPtr S__notmuch_messages\r
93     type MessagePtr = ForeignPtr S__notmuch_message\r
94     newtype Query = Query (ForeignPtr S__notmuch_query)\r
95     data MessagesRef = QueryMessages { qmpp :: Query, msp :: MessagesPtr }\r
96                      | ThreadMessages { tmpp :: Thread, msp :: MessagesPtr }\r
97                      | MessageMessages { mmspp :: Message, msp :: MessagesPtr }\r
98     data Message = MessagesMessage { msmpp :: MessagesRef, mp :: MessagePtr }\r
99                  | Message { mp :: MessagePtr }\r
100     type Messages = [Message]\r
101 \r
102 As seen in the Valgrind dump given in my previous message, it seems that\r
103 the Query object is being freed before the Messages object. Since the\r
104 Messages object is a child of the Query object, this fails.\r
105 \r
106 In my case, I'm calling queryMessages which begins by issuing a given\r
107 notmuch Query, resulting in a MessagesPtr. This is then packaged into a\r
108 QueryMessages object which is then passed off to\r
109 unpackMessages. unpackMessages iterates over this collection, creating\r
110 MessagesMessage objects which themselves refer to the QueryMessages\r
111 object. Finally, these MessagesMessage objects are packed into a list,\r
112 resulting in a Messages object. Thus we have the following chain of\r
113 references,\r
114 \r
115         MessagesMessage\r
116               |   \r
117               |  msmpp\r
118               \/\r
119         QueryMessages\r
120               |\r
121               |  qmpp\r
122               \/\r
123             Query\r
124 \r
125 As we can see, each MessagesMessage object in the Messages list\r
126 resulting from queryMessages holds a reference to the Query object from\r
127 which it originated. For this reason, I fail to see how it is possible\r
128 that the RTS would attempt to free the Query before freeing the\r
129 MessagesPtr. Did I miss something in my analysis? Are there tools for\r
130 debugging issues such as this? Perhaps this is a bug in the GC?\r
131 \r
132 Any help at all would be greatly appreciated.\r
133 \r
134 Cheers,\r
135 \r
136 - Ben\r