<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 22:01:30 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[CXX-1129] Legacy 1.1.x driver calls abort() when query/document&apos;s size is less but close to 16Mb</title>
                <link>https://jira.mongodb.org/browse/CXX-1129</link>
                <project id="11980" key="CXX">C++ Driver</project>
                    <description>&lt;p&gt;We are encountering sporadic crashes of the legacy 1.1.x driver. Debugging revealed that the driver&apos;s code contains subtle discrepancies in &lt;tt&gt;uassert()&lt;/tt&gt; checks (normal driver exceptions) and &lt;tt&gt;invariant()&lt;/tt&gt; calls that eventually lead to &lt;tt&gt;abort()&lt;/tt&gt; and crash our system. These discrepancies manifest themselves for BSON objects whose size is less than the default maximum size (16777216) but more than 16777216 - 8200 = 16769016.&lt;/p&gt;

&lt;p&gt;Please see the following debugging session which illustrates the problem.&lt;/p&gt;

&lt;p&gt;{{&lt;br/&gt;
&lt;span class=&quot;error&quot;&gt;&amp;#91;...&amp;#93;&lt;/span&gt;&lt;br/&gt;
Program received signal SIGABRT, Aborted.&lt;br/&gt;
0x00007ffff6f615e5 in raise () from /lib64/libc.so.6&lt;/p&gt;

&lt;p&gt;(gdb) bt&lt;br/&gt;
#0  0x00007ffff6f615e5 in raise () from /lib64/libc.so.6&lt;br/&gt;
#1  0x00007ffff6f62dc5 in abort () from /lib64/libc.so.6&lt;br/&gt;
#2  0x00007ffff6868aef in mongo::invariantFailed (expr=0x7ffff6887f38 &quot;_fits(batch.get(), *batch_iter)&quot;, file=0x7ffff6887f10 &quot;src/mongo/client/command_writer.cpp&quot;, line=51)&lt;br/&gt;
    at src/mongo/util/assert_util.cpp:91&lt;br/&gt;
#3  0x00007ffff67e9281 in mongo::CommandWriter::write (this=0x618a10, ns=..., write_operations=std::vector of length 1, capacity 1 = &lt;/p&gt;
{...}, ordered=true,&lt;br/&gt;
    bypassDocumentValidation=false, writeConcern=0x61a560, writeResult=0x7fffffffdd00) at src/mongo/client/command_writer.cpp:51&lt;br/&gt;
#4  0x00007ffff67fac97 in mongo::DBClientBase::_write (this=0x61a4e0, ns=&quot;test1.test1&quot;, writes=std::vector of length 1, capacity 1 = {...}
&lt;p&gt;, ordered=true,&lt;br/&gt;
    bypassDocumentValidation=false, writeConcern=0x0, writeResult=0x7fffffffdd00) at src/mongo/client/dbclient.cpp:2056&lt;br/&gt;
#5  0x00007ffff67fb57c in mongo::DBClientBase::update (this=0x61a4e0, ns=&quot;test1.test1&quot;, query=..., obj=..., flags=1, wc=0x0) at src/mongo/client/dbclient.cpp:2143&lt;br/&gt;
#6  0x00007ffff67fb399 in mongo::DBClientBase::update (this=0x61a4e0, ns=&quot;test1.test1&quot;, query=..., obj=..., upsert=true, multi=false, wc=0x0) at src/mongo/client/dbclient.cpp:2127&lt;/p&gt;

&lt;p&gt;(gdb) fr 3&lt;br/&gt;
#3  0x00007ffff67e9281 in mongo::CommandWriter::write (this=0x618a10, ns=..., write_operations=std::vector of length 1, capacity 1 = &lt;/p&gt;
{...}, ordered=true,&lt;br/&gt;
    bypassDocumentValidation=false, writeConcern=0x61a560, writeResult=0x7fffffffdd00) at src/mongo/client/command_writer.cpp:51&lt;br/&gt;
51	        invariant(_fits(batch.get(), *batch_iter));&lt;br/&gt;
(gdb) l&lt;br/&gt;
46	        boost::scoped_ptr&amp;lt;BSONArrayBuilder&amp;gt; batch(new BSONArrayBuilder);&lt;br/&gt;
47	        std::vector&amp;lt;WriteOperation*&amp;gt;::const_iterator batch_iter = batch_begin;&lt;br/&gt;
48&lt;br/&gt;
49	        // We must be able to fit the first item of the batch. Otherwise, the calling code&lt;br/&gt;
50	        // passed an over size write operation in violation of our contract.&lt;br/&gt;
51	        invariant(_fits(batch.get(), *batch_iter));&lt;br/&gt;
52&lt;br/&gt;
53	        // Set the current operation type&lt;br/&gt;
54	        const WriteOpType batchOpType = (*batch_iter)-&amp;gt;operationType();&lt;br/&gt;
55&lt;br/&gt;
&lt;br/&gt;
(gdb) bre 51&lt;br/&gt;
&lt;span class=&quot;error&quot;&gt;&amp;#91;...&amp;#93;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
Breakpoint 1, mongo::CommandWriter::write (this=0x618a10, ns=..., write_operations=std::vector of length 1, capacity 1 = {...}
&lt;p&gt;, ordered=true, bypassDocumentValidation=false,&lt;br/&gt;
    writeConcern=0x61a560, writeResult=0x7fffffffdd00) at src/mongo/client/command_writer.cpp:51&lt;br/&gt;
51	        invariant(_fits(batch.get(), *batch_iter));&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;error&quot;&gt;&amp;#91;...&amp;#93;&lt;/span&gt;&lt;br/&gt;
(gdb) s&lt;br/&gt;
mongo::CommandWriter::_fits (this=0x618a10, builder=0x61eef0, operation=0x61dfa0) at src/mongo/client/command_writer.cpp:112&lt;br/&gt;
112	    int opSize = operation-&amp;gt;incrementalSize();&lt;br/&gt;
(gdb) n&lt;br/&gt;
113	    int maxSize = _client-&amp;gt;getMaxBsonObjectSize();&lt;br/&gt;
(gdb) n&lt;br/&gt;
116	    uassert(0, &quot;update command exceeds maxBsonObjectSize&quot;, opSize &amp;lt;= maxSize);&lt;br/&gt;
(gdb) n&lt;br/&gt;
118	    return (builder-&amp;gt;len() + opSize + kOverhead) &amp;lt;= maxSize;&lt;br/&gt;
(gdb) print opSize&lt;br/&gt;
$2 = 16773902&lt;br/&gt;
(gdb) print maxSize&lt;br/&gt;
$3 = 16777216&lt;br/&gt;
(gdb) print opSize &amp;lt;= maxSize&lt;br/&gt;
$4 = true&lt;br/&gt;
(gdb) print builder-&amp;gt;len() + opSize + kOverhead &amp;lt;= maxSize&lt;br/&gt;
$5 = false&lt;br/&gt;
(gdb) print builder-&amp;gt;len() + kOverhead&lt;br/&gt;
$6 = 8200&lt;br/&gt;
(gdb) print opSize &amp;lt;= maxSize - builder-&amp;gt;len() - kOverhead&lt;br/&gt;
$7 = false&lt;br/&gt;
}}&lt;/p&gt;


&lt;p&gt;Please also note that similar &lt;tt&gt;uassert()&lt;/tt&gt; checks are passed even before:&lt;/p&gt;

&lt;p&gt;{{&lt;br/&gt;
(gdb) fr 3&lt;br/&gt;
#3  0x00007ffff67fb57c in mongo::DBClientBase::update (this=0x61a4e0, ns=&quot;test1.test1&quot;, query=..., obj=..., flags=1, wc=0x0) at src/mongo/client/dbclient.cpp:2143&lt;br/&gt;
2143	    _write(ns, updates.ops, true, bypassDocumentValidation, wc, &amp;amp;writeResult);&lt;br/&gt;
(gdb) l -&lt;br/&gt;
&lt;font color=&quot;red&quot;&gt;&lt;br/&gt;
2133	    uassert(0,&lt;br/&gt;
2134	            &quot;update selector exceeds maxBsonObjectSize&quot;,&lt;br/&gt;
2135	            query.obj.objsize() &amp;lt;= getMaxBsonObjectSize());&lt;br/&gt;
2136	    uassert(&lt;br/&gt;
2137	        0, &quot;update document exceeds maxBsonObjectSize&quot;, obj.objsize() &amp;lt;= getMaxBsonObjectSize());&lt;/font&gt;&lt;br/&gt;
2138	    updates.enqueue(new UpdateWriteOperation(query.obj, obj, flags));&lt;br/&gt;
2139&lt;br/&gt;
2140	    bool bypassDocumentValidation = flags &amp;amp; UpdateOption_BypassDocumentValidation;&lt;br/&gt;
2141&lt;br/&gt;
2142	    WriteResult writeResult;&lt;br/&gt;
2143	    _write(ns, updates.ops, true, bypassDocumentValidation, wc, &amp;amp;writeResult);&lt;br/&gt;
2144	}&lt;br/&gt;
}}&lt;/p&gt;</description>
                <environment>CentOS 6.8</environment>
        <key id="331470">CXX-1129</key>
            <summary>Legacy 1.1.x driver calls abort() when query/document&apos;s size is less but close to 16Mb</summary>
                <type id="1" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14703&amp;avatarType=issuetype">Bug</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="2">Won&apos;t Fix</resolution>
                                        <assignee username="david.golden@mongodb.com">David Golden</assignee>
                                    <reporter username="neoxic">Arseny Vakhrushev</reporter>
                        <labels>
                            <label>legacy-cxx</label>
                    </labels>
                <created>Sun, 13 Nov 2016 00:42:13 +0000</created>
                <updated>Wed, 28 Feb 2018 18:52:29 +0000</updated>
                            <resolved>Tue, 7 Feb 2017 18:52:20 +0000</resolved>
                                    <version>legacy-1.1.0</version>
                    <version>legacy-1.1.1</version>
                    <version>legacy-1.1.2</version>
                                                    <component>Implementation</component>
                                        <votes>0</votes>
                                    <watches>3</watches>
                                                                                                                <comments>
                            <comment id="1494145" author="david.golden" created="Tue, 7 Feb 2017 18:52:20 +0000"  >&lt;p&gt;After further discussion internally about resource planning, I&apos;m closing this ticket as &quot;Won&apos;t Fix&quot;.&lt;/p&gt;</comment>
                            <comment id="1432920" author="david.golden" created="Mon, 14 Nov 2016 03:25:13 +0000"  >&lt;p&gt;One of the many reasons we encourage people to migrate to the stable mongocxx release is that you have much greater control.  Among other things, you can build up bson objects with bsoncxx and check their length as you go.&lt;/p&gt;</comment>
                            <comment id="1432816" author="neoxic" created="Sun, 13 Nov 2016 19:29:03 +0000"  >&lt;p&gt;I appreciate your feedback, David. We are aware that the legacy driver is not getting anything other than critical - we wouldn&apos;t bother you guys otherwise. We can&apos;t see though how things like this are not critical to be honest. They can cause abortions and hence lead to stability issues and data loss in the calling code. What else is critical then? &lt;img class=&quot;emoticon&quot; src=&quot;https://jira.mongodb.org/images/icons/emoticons/smile.png&quot; height=&quot;16&quot; width=&quot;16&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/p&gt;

&lt;p&gt;It&apos;s also not always possible to check against a document&apos;s size when the legacy driver is wrapped around as a module for another language and a document is formed from a native associative array or table for example. The issue needs to be propagated upstream in this case.&lt;/p&gt;</comment>
                            <comment id="1432748" author="david.golden" created="Sun, 13 Nov 2016 08:40:47 +0000"  >&lt;p&gt;Thanks for the bug report.  At one time, the server required update commands to fit into the maximum BSON object size, so the assertion checks that there is room for 8kb overhead for the command.  The server currently allows a little extra overhead above the max BSON object size, but the assertions in the legacy driver haven&apos;t been updated to match.  There is also a related problem in &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-12305&quot; title=&quot;Allow command request and response BSON objects to exceed 16MB&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-12305&quot;&gt;SERVER-12305&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The legacy driver is getting critical fixes only, so we don&apos;t anticipate putting resources against this bug any time soon.  The workaround as you found is to ensure that your documents are smaller than 16MB less 8kb.&lt;/p&gt;

&lt;p&gt;Regards,&lt;br/&gt;
David&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hrdt0v:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>