[SERVER-33125] Segfault caused by apparent error in codegen for exception unwinding on s390x Created: 05/Feb/18  Updated: 08/Jan/24  Resolved: 09/Feb/18

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

Type: Bug Priority: Major - P3
Reporter: Justin Seyster Assignee: Justin Seyster
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-32431 IDL generated code seg faults on s390x Closed
is related to SERVER-34873 Fix problems caused by unwind handlin... Closed
Backwards Compatibility: Fully Compatible
Operating System: ALL
Participants:
Linked BF Score: 0

 Description   

On s390x, when this call to parseElement results in an exception, exception unwinding triggers a call to the FieldPath destructor, but that destructor gets called on address 0x0. Inspection of the disassembly reveals that the exception unwinding code is incorrectly attempting to read the address of the FieldPath object from a volatile (caller-save) register, which has been clobbered with a 0 value.

As a workaround, we can assign the FieldPath to a named variable, instead of constructing it within the argument list to ProjectTypeParser::parseElement().



 Comments   
Comment by Githook User [ 17/Nov/18 ]

Author:

{'name': 'Andrew Morrow', 'email': 'acm@mongodb.com', 'username': 'acmorrow'}

Message: SERVER-34873 Revert "SERVER-33125 Work around codegen error in s390x exception unwinding."

This reverts commit 85b39d411987431a8c37b1de267b167a384ea9b3.
Branch: master
https://github.com/mongodb/mongo/commit/c5f382a9aae82c2e87362fb0da3cc1d08e9edbb5

Comment by Githook User [ 09/Feb/18 ]

Author:

{'email': 'justin.seyster@mongodb.com', 'name': 'Justin Seyster', 'username': 'jseyster'}

Message: SERVER-33125 Work around codegen error in s390x exception unwinding.
Branch: master
https://github.com/mongodb/mongo/commit/85b39d411987431a8c37b1de267b167a384ea9b3

Comment by Justin Seyster [ 07/Feb/18 ]

While investigating the workaround for this crasher, I realized I made a mistake in my initial diagnosis. I misread the standard, and the register I thought is volatile (r7) is actually saved (callee-save). That means that the code that the ~FieldPath call site is actually correct in expecting r7 to still hold the address to the FieldPath it wants to destroy.

I observed where on the stack ProjectTypeParser::parseElememt() saved the value of r7 and set a watchpoint, which allowed me to confirm that the value is actually getting clobbered on the stack. That of course opens up the possibility that the clobbering is because of a code error, but whatever is doing the clobbering is part of the exception unwinding machinery. Unfortunately, I don't know nearly enough about exception unwinding to understand what went wrong. I still suspect a codegen error, because the crash only occurs on s390x, ASAN does not find any memory corruption, and seemingly insignificant code changes cause the crash to go away.

For reference, here is the top of the backtrace for the write that clobbers the saved value for r7:

Old value = (mongo::FieldPath *) 0x3ffca97b0a0
New value = (mongo::FieldPath *) 0x0
0x000003fffdc077c8 in _Unwind_SetGR () from /lib64/libgcc_s.so.1
(gdb) bt
#0  0x000003fffdc077c8 in _Unwind_SetGR () from /lib64/libgcc_s.so.1
#1  0x000002aa02383224 in __cxxabiv1::__gxx_personality_v0 (version=<optimized out>, actions=<optimized out>, exception_class=<optimized out>, ue_header=0x2aa07af32d8, context=0x3ffca97ac08) at ../../../../gcc-5.4.0/libstdc++-v3/libsupc++/eh_personality.cc:715
#2  0x000003fffdc09c84 in ?? () from /lib64/libgcc_s.so.1
#3  0x000003fffdc0a274 in _Unwind_Resume () from /lib64/libgcc_s.so.1
#4  0x000002aa01ae007a in ~intrusive_ptr (this=<optimized out>, __in_chrg=<optimized out>) at src/third_party/boost-1.60.0/boost/smart_ptr/intrusive_ptr.hpp:97
#5  ~SharedBuffer (this=<optimized out>, __in_chrg=<optimized out>) at src/mongo/util/shared_buffer.h:42
#6  ~SharedBufferAllocator (this=<optimized out>, __in_chrg=<optimized out>) at src/mongo/bson/util/builder.h:79
#7  ~_BufBuilder (this=<optimized out>, __in_chrg=<optimized out>) at src/mongo/bson/util/builder.h:157
#8  ~StringBuilderImpl (this=<optimized out>, __in_chrg=<optimized out>) at src/mongo/bson/util/builder.h:385
#9  ~stream (this=<optimized out>, __in_chrg=<optimized out>) at src/mongo/util/mongoutils/str.h:57
#10 operator() (__closure=<optimized out>) at src/mongo/db/pipeline/parsed_aggregation_projection.cpp:232
#11 mongo::parsed_aggregation_projection::(anonymous namespace)::ProjectTypeParser::parseElement (this=0x2aa01e2d948 <std::vector<unsigned long, std::allocator<unsigned long> >::_M_emplace_back_aux<unsigned long>(unsigned long&&)+152>, elem=..., pathToElem=...)
    at src/mongo/db/pipeline/parsed_aggregation_projection.cpp:232
#12 0x000002aa01ae150e in parse (this=0x3ffca97b070) at src/mongo/db/pipeline/parsed_aggregation_projection.cpp:180
#13 parse (spec=...) at src/mongo/db/pipeline/parsed_aggregation_projection.cpp:165
#14 mongo::parsed_aggregation_projection::ParsedAggregationProjection::create (expCtx=..., spec=...) at src/mongo/db/pipeline/parsed_aggregation_projection.cpp:291

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