Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-74530

Segfault in SBE's object destructor when passed an empty object

    • Type: Icon: Bug Bug
    • Resolution: Gone away
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • ALL
    • Hide

      This can be reproduced by running mongod with SBE on and optimizations off:

      ./build/install/bin/mongod --setParameter featureFlagSbeFull=true --setParameter enableTestCommands=true --setParameter failpoint.disablePipelineOptimization="{mode:'alwaysOn'}"
      

      and then in the mongo shell:

      const coll = db.example;
      coll.drop();
      assert.commandWorked(coll.insert({_id: 0}));
      
      let onError = {};
      coll.aggregate(
                      {$project: {date: {$dateFromString: {dateString: "invalid", onError: onError}}}});
      
      Show
      This can be reproduced by running mongod with SBE on and optimizations off: ./build/install/bin/mongod --setParameter featureFlagSbeFull= true --setParameter enableTestCommands= true --setParameter failpoint.disablePipelineOptimization= "{mode: 'alwaysOn' }" and then in the mongo shell: const coll = db.example; coll.drop(); assert .commandWorked(coll.insert({_id: 0})); let onError = {}; coll.aggregate( {$project: {date: {$dateFromString: {dateString: "invalid" , onError: onError}}}});
    • QE 2023-03-20

      We are hitting a segmentation fault, because an already-destructed object is being destructed a second time.

      Here is a stack trace of the first time the destructor is called:

      #0  mongo::sbe::value::Object::~Object (this=0x55555b3e34a0)
          at src/mongo/db/exec/sbe/values/value.h:722
      #1  0x00007ffff1027521 in mongo::sbe::value::releaseValueDeep (
          tag=<optimized out>, val=93825091384480)
          at src/mongo/db/exec/sbe/values/value.cpp:305
      #2  0x00007ffff263368a in mongo::sbe::value::releaseValue (tag=-60,
          val=93825091384480) at src/mongo/db/exec/sbe/values/value.h:292
      #3  mongo::sbe::vm::ByteCode::popAndReleaseStack (this=0x55555bd73d70)
          at src/mongo/db/exec/sbe/vm/vm.h:1483
      #4  mongo::sbe::vm::ByteCode::runInternal (this=<optimized out>,
          code=0x55555b2b4600, position=<optimized out>)
          at src/mongo/db/exec/sbe/vm/vm.cpp:6842
      #5  0x00007ffff261caaf in mongo::sbe::vm::ByteCode::runLambdaInternal (
          this=0x55555bd73d70, code=0x55555b3e34a0, position=93825091384480)
          at src/mongo/db/exec/sbe/vm/vm.cpp:5934
      #6  0x00007ffff2632f9f in mongo::sbe::vm::ByteCode::runInternal (
          this=<optimized out>, this@entry=0x55555bd73d70,
          code=code@entry=0x55555b2b4600, position=<optimized out>, position@entry=0)
          at src/mongo/db/exec/sbe/vm/vm.cpp:6541
      #7  0x00007ffff2636088 in mongo::sbe::vm::ByteCode::run (this=0x55555bd73d70,
          code=0x55555b2b4600) at src/mongo/db/exec/sbe/vm/vm.cpp:6958
      #8  0x00007ffff27ee39b in mongo::sbe::ProjectStage::getNext (
          this=<optimized out>) at src/mongo/db/exec/sbe/stages/project.cpp:96
      #9  0x00007ffff3ba0466 in mongo::fetchNextImpl<mongo::BSONObj> (
          root=0x55555bd73c80, resultSlot=0x5555561ec528, recordIdSlot=0x0,
          out=out@entry=0x7fffd91281c8, dlOut=dlOut@entry=0x0, returnOwnedBson=true)
          at src/mongo/db/query/plan_executor_sbe.cpp:537
      #10 0x00007ffff3b9fefd in mongo::PlanExecutorSBE::getNextImpl<mongo::BSONObj> (
          this=this@entry=0x55555b4fe300, out=out@entry=0x7fffd91281c8,
          dlOut=dlOut@entry=0x0) at src/mongo/db/query/plan_executor_sbe.cpp:303
      #11 0x00007ffff3b9e659 in mongo::PlanExecutorSBE::getNext (
          this=0x55555b4fe300, out=0x7fffd9128300, dlOut=0x0)
          at src/mongo/db/query/plan_executor_sbe.cpp:222
      

      And the second time:

      #0  mongo::sbe::value::Object::~Object (this=0x55555b3e34a0)
          at src/mongo/db/exec/sbe/values/value.h:722
      #1  0x00007ffff1027521 in mongo::sbe::value::releaseValueDeep (
          tag=<optimized out>, val=93825091384480)
          at src/mongo/db/exec/sbe/values/value.cpp:305
      #2  0x00007ffff263368a in mongo::sbe::value::releaseValue (tag=-60,
          val=93825091384480) at src/mongo/db/exec/sbe/values/value.h:292
      #3  mongo::sbe::vm::ByteCode::popAndReleaseStack (this=0x55555bd73d70)
          at src/mongo/db/exec/sbe/vm/vm.h:1483
      #4  mongo::sbe::vm::ByteCode::runInternal (this=<optimized out>,
          code=0x55555b2b4600, position=<optimized out>)
          at src/mongo/db/exec/sbe/vm/vm.cpp:6842
      #5  0x00007ffff261caaf in mongo::sbe::vm::ByteCode::runLambdaInternal (
          this=0x55555bd73d70, code=0x55555b3e34a0, position=93825101921096)
          at src/mongo/db/exec/sbe/vm/vm.cpp:5934
      #6  0x00007ffff2632f9f in mongo::sbe::vm::ByteCode::runInternal (
          this=<optimized out>, this@entry=0x55555bd73d70,
          code=code@entry=0x55555b2b4600, position=<optimized out>, position@entry=0)
          at src/mongo/db/exec/sbe/vm/vm.cpp:6541
      #7  0x00007ffff2636088 in mongo::sbe::vm::ByteCode::run (this=0x55555bd73d70,
          code=0x55555b2b4600) at src/mongo/db/exec/sbe/vm/vm.cpp:6958
      #8  0x00007ffff27ee39b in mongo::sbe::ProjectStage::getNext (
          this=<optimized out>) at src/mongo/db/exec/sbe/stages/project.cpp:96
      #9  0x00007ffff3ba0466 in mongo::fetchNextImpl<mongo::BSONObj> (
          root=0x55555bd73c80, resultSlot=0x5555561ec528, recordIdSlot=0x0,
          out=out@entry=0x7fffd91281c8, dlOut=dlOut@entry=0x0, returnOwnedBson=true)
          at src/mongo/db/query/plan_executor_sbe.cpp:537
      #10 0x00007ffff3b9fefd in mongo::PlanExecutorSBE::getNextImpl<mongo::BSONObj> (
          this=this@entry=0x55555b4fe300, out=out@entry=0x7fffd91281c8,
          dlOut=dlOut@entry=0x0) at src/mongo/db/query/plan_executor_sbe.cpp:303
      #11 0x00007ffff3b9e659 in mongo::PlanExecutorSBE::getNext (
          this=0x55555b4fe300, out=0x7fffd9128300, dlOut=0x0)
          at src/mongo/db/query/plan_executor_sbe.cpp:222
      

      The only visible difference between these two stack traces is in mongo::sbe::vm::ByteCode::runLambdaInternal: the position has increased.

      Stepping through the code in GDB, it seems like the second destructor is being called immediately afterwards, and this happens right after builtInDateFromString returns onError.

            Assignee:
            jennifer.peshansky@mongodb.com Jennifer Peshansky (Inactive)
            Reporter:
            jennifer.peshansky@mongodb.com Jennifer Peshansky (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: