[SERVER-32431] IDL generated code seg faults on s390x Created: 20/Dec/17  Updated: 08/Jan/24  Resolved: 27/Dec/17

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: 3.7.1

Type: Bug Priority: Major - P3
Reporter: Mark Benvenuto Assignee: Mark Benvenuto
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Related
related to SERVER-32467 Remove s390x compiler workaround Closed
is related to SERVER-33125 Segfault caused by apparent error in ... Closed
is related to SERVER-34873 Fix problems caused by unwind handlin... Closed
Backwards Compatibility: Fully Compatible
Operating System: ALL
Sprint: Platforms 2018-01-15
Participants:
Linked BF Score: 0

 Description   

IDL generated code seg faults only on s390x as a result of SERVER-32263.

It appears to be a compiler bug with GCC 5.4.0. The destructor: <std::vector<mongo::write_ops::UpdateOpEntry, std::allocator<mongo::write_ops::UpdateOpEntry> >::~vector()> gets called with the wrong this pointer during exception unwind.

This bug affects the array deserializers. The change in SERVER-32263 did not affect the generated code for array deserializers in question, but it did affect the overall parseProtected method.

A workaround is assign the return type to a local variable:

                    self._writer.write_line('auto abc = %s;' % (array_value))
                    self._writer.write_line('values.emplace_back(abc);')



 Comments   
Comment by Mark Benvenuto [ 08/Feb/18 ]

Copy of original build failure analysis:

When an exception is thrown at the following location:

#0  __cxxabiv1::__cxa_throw (obj=0x2aa01032978, tinfo=0x2aa007d4318 <typeinfo for mongo::error_details::throwExceptionForStatus(mongo::Status const&)::NonspecificAssertionException>,
    dest=0x2aa002b55e0 <mongo::error_details::NonspecificAssertionException::~NonspecificAssertionException()>) at ../../../../gcc-5.4.0/libstdc++-v3/libsupc++/eh_throw.cc:63
#1  0x000002aa001998ae in mongo::error_details::throwExceptionForStatus (status=...) at build/opt/mongo/base/error_codes.cpp:1679
#2  0x000002aa0019cab0 in mongo::uassertedWithLocation (msgid=<optimized out>, msg=..., file=<optimized out>, line=<optimized out>) at src/mongo/util/assert_util.cpp:200
#3  0x000002aa00190e22 in mongo::IDLParserErrorContext::throwUnknownField (this=<optimized out>, fieldName=...) at src/mongo/idl/idl_parser.cpp:191
#4  0x000002aa001d6dce in mongo::write_ops::UpdateOpEntry::parseProtected (this=this@entry=0x3ffffffd060, ctxt=..., bsonObject=<error reading variable: value has been optimized out>) at build/opt/mongo/db/ops/write_ops_gen.cpp:231
#5  0x000002aa001d7614 in mongo::write_ops::UpdateOpEntry::parse (ctxt=..., bsonObject=<error reading variable: value has been optimized out>) at build/opt/mongo/db/ops/write_ops_gen.cpp:124
#6  0x000002aa001db9f2 in mongo::write_ops::Update::parseProtected (this=0x3fffdfa2f40, this@entry=0x3ffffffd580, ctxt=..., request=...) at build/opt/mongo/db/ops/write_ops_gen.cpp:1063
#7  0x000002aa001dc21a in mongo::write_ops::Update::parse (ctxt=..., request=...) at build/opt/mongo/db/ops/write_ops_gen.cpp:960
#8  0x000002aa001d1be0 in mongo::UpdateOp::parse (request=...) at src/mongo/db/ops/write_ops_parsers.cpp:165
#9  0x000002aa001ae326 in mongo::(anonymous namespace)::UnitTest__CommandWriteOpsParsers__GarbageFieldsInUpdateDoc::_doTest (this=<optimized out>) at src/mongo/db/ops/write_ops_parsers_test.cpp:141
#10 0x000002aa001c6e90 in mongo::unittest::Test::run (this=0x3ffffffd958) at src/mongo/unittest/unittest.cpp:175
#11 0x000002aa001abf80 in mongo::unittest::Suite::runTestObject<mongo::(anonymous namespace)::UnitTest__CommandWriteOpsParsers__GarbageFieldsInUpdateDoc> () at src/mongo/unittest/unittest.h:422
#12 0x000002aa001c9496 in std::function<void ()>::operator()() const (this=<optimized out>) at /opt/mongodbtoolchain/v2/include/c++/5.4.0/functional:2267
#13 mongo::unittest::TestHolder::run (this=<optimized out>) at src/mongo/unittest/unittest.h:263
#14 mongo::unittest::Suite::run (this=<optimized out>, filter=..., runsPerTest=runsPerTest@entry=1) at src/mongo/unittest/unittest.cpp:295
#15 0x000002aa001cae9c in mongo::unittest::Suite::run (suites=..., filter=..., runsPerTest=<optimized out>) at src/mongo/unittest/unittest.cpp:354
#16 0x000002aa001a111e in main (argc=<optimized out>, argv=0x3fffffff438, envp=<optimized out>) at src/mongo/unittest/unittest_main.cpp:93

We hit the following seg fault:

Program received signal SIGSEGV, Segmentation fault.
std::_Destroy_aux<false>::__destroy<mongo::write_ops::UpdateOpEntry*> (__last=<optimized out>, __first=0x474e5543432b2b00) at /opt/mongodbtoolchain/v2/include/c++/5.4.0/bits/stl_construct.h:103
103                 std::_Destroy(std::__addressof(*__first));
(gdb) bt
#0  std::_Destroy_aux<false>::__destroy<mongo::write_ops::UpdateOpEntry*> (__last=<optimized out>, __first=0x474e5543432b2b00) at /opt/mongodbtoolchain/v2/include/c++/5.4.0/bits/stl_construct.h:103
#1  std::_Destroy<mongo::write_ops::UpdateOpEntry*> (__last=<optimized out>, __first=<optimized out>) at /opt/mongodbtoolchain/v2/include/c++/5.4.0/bits/stl_construct.h:126
#2  std::_Destroy<mongo::write_ops::UpdateOpEntry*, mongo::write_ops::UpdateOpEntry> (__last=0x2aa00429c18 <__gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Exception*)>, __first=<optimized out>)
    at /opt/mongodbtoolchain/v2/include/c++/5.4.0/bits/stl_construct.h:151
#3  std::vector<mongo::write_ops::UpdateOpEntry, std::allocator<mongo::write_ops::UpdateOpEntry> >::~vector (this=0x2aa01032958, __in_chrg=<optimized out>) at /opt/mongodbtoolchain/v2/include/c++/5.4.0/bits/stl_vector.h:424
#4  0x000002aa001dbc02 in mongo::write_ops::Update::parseProtected (this=0x0, this@entry=0x3ffffffd580, ctxt=..., request=...) at build/opt/mongo/db/ops/write_ops_gen.cpp:1047
#5  0x000002aa001dc21a in mongo::write_ops::Update::parse (ctxt=..., request=...) at build/opt/mongo/db/ops/write_ops_gen.cpp:960
#6  0x000002aa001d1be0 in mongo::UpdateOp::parse (request=...) at src/mongo/db/ops/write_ops_parsers.cpp:165
#7  0x000002aa001ae326 in mongo::(anonymous namespace)::UnitTest__CommandWriteOpsParsers__GarbageFieldsInUpdateDoc::_doTest (this=<optimized out>) at src/mongo/db/ops/write_ops_parsers_test.cpp:141
#8  0x000002aa001c6e90 in mongo::unittest::Test::run (this=0x3ffffffd958) at src/mongo/unittest/unittest.cpp:175
#9  0x000002aa001abf80 in mongo::unittest::Suite::runTestObject<mongo::(anonymous namespace)::UnitTest__CommandWriteOpsParsers__GarbageFieldsInUpdateDoc> () at src/mongo/unittest/unittest.h:422
#10 0x000002aa001c9496 in std::function<void ()>::operator()() const (this=<optimized out>) at /opt/mongodbtoolchain/v2/include/c++/5.4.0/functional:2267
#11 mongo::unittest::TestHolder::run (this=<optimized out>) at src/mongo/unittest/unittest.h:263
#12 mongo::unittest::Suite::run (this=<optimized out>, filter=..., runsPerTest=runsPerTest@entry=1) at src/mongo/unittest/unittest.cpp:295
#13 0x000002aa001cae9c in mongo::unittest::Suite::run (suites=..., filter=..., runsPerTest=<optimized out>) at src/mongo/unittest/unittest.cpp:354
#14 0x000002aa001a111e in main (argc=<optimized out>, argv=0x3fffffff438, envp=<optimized out>) at src/mongo/unittest/unittest_main.cpp:93

The following patch will workaround the crash. It appears to only affect s390x, and no other architecture.

diff --git a/buildscripts/idl/idl/generator.py b/buildscripts/idl/idl/generator.py
index 40a81f1..9eb7353 100644
--- a/buildscripts/idl/idl/generator.py
+++ b/buildscripts/idl/idl/generator.py
@@ -815,7 +815,8 @@ class _CppSourceFileWriter(_CppFileWriterBase):
 
                 with self._predicate(_get_bson_type_check('arrayElement', 'arrayCtxt', field)):
                     array_value = self._gen_field_deserializer_expression('arrayElement', field)
-                    self._writer.write_line('values.emplace_back(%s);' % (array_value))
+                    self._writer.write_line('auto abc = %s;' % (array_value))
+                    self._writer.write_line('values.push_back(abc);')

The seg fault address maps to a string:

(gdb) x /20c 0x2aa01033958
0x2aa01033958:  71 'G'  78 'N'  85 'U'  67 'C'  67 'C'  43 '+'  43 '+'  0 '\000'
0x2aa01033960:  0 '\000'        0 '\000'        2 '\002'        -86 '\252'      0 '\000'        66 'B'  -99 '\235'      96 '`'
0x2aa01033968:  0 '\000'        0 '\000'        0 '\000'        0 '\000'

Comment by Githook User [ 27/Dec/17 ]

Author:

{'email': 'mark.benvenuto@mongodb.com', 'username': 'markbenvenuto', 'name': 'Mark Benvenuto'}

Message: SERVER-32431 IDL generated code seg faults on s390x
Branch: master
https://github.com/mongodb/mongo/commit/86afc6ed8216e7b31ea6ab9c13d7bac470ee0774

Generated at Thu Feb 08 04:30:13 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.