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

Ensure complex SBE expressions properly manage lifetime of stack values

    • Type: Icon: Task Task
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 6.2.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • Fully Compatible
    • QE 2022-11-28
    • 10

      When an expression is retrieving data from a value that is owned by the stack, it should either ensure that it has a lifetime bigger than the lifetime of the return value, or make it a stack-owned copy.

      Example:

      TEST_F(SBEBuiltinExtractSubArrayTest, MemoryManagement) {
          auto array = makeArray(BSON_ARRAY("Item#1"
                                            << "Item#2"
                                            << "Item#3"
                                            << "Item#4"));
      
          // Run getElement(0) on the subarray holding just the last entry in the above array.
          auto extractFromSubArrayExpr = makeE<EFunction>(
              "getElement",
              makeEs(makeE<EFunction>(
                         "extractSubArray",
                                      makeEs(makeE<EConstant>(array.first, array.second),
                                             makeE<EConstant>(value::TypeTags::NumberInt32, 1),
                                             makeE<EConstant>(value::TypeTags::NumberInt32, 2))),
                     makeE<EConstant>(value::TypeTags::NumberInt32, 0)));
      
          auto compiledExpr = compileExpression(*extractFromSubArrayExpr);
      
          auto [tag, value] = runCompiledExpression(compiledExpr.get());
          std::cout << std::make_pair(tag, value) << std::endl;
          ASSERT_TRUE(value::isString(tag));
          ASSERT_EQ("Item#3", value::getRawStringView(tag, value));
      }
      

      The extractSubArray instruction creates a new stack-owned array, and getElement returns a shared value that points to deleted memory by the time runCompiledExpression attempts to copy.

       	KernelBase.dll!wil::details::DebugBreak(void)	Unknown
       	db_sbe_test.exe!mongo::invariantFailed(const char * expr, const char * file, unsigned int line) Line 142	C++
       	[Inline Frame] db_sbe_test.exe!mongo::invariantWithLocation(const bool &) Line 74	C++
       	db_sbe_test.exe!mongo::sbe::value::makeBigString(mongo::StringData input) Line 1110	C++
       	db_sbe_test.exe!mongo::sbe::value::copyValue(mongo::sbe::value::TypeTags tag, unsigned __int64 val) Line 1452	C++
      >	[Inline Frame] db_sbe_test.exe!mongo::sbe::EExpressionTestFixture::runCompiledExpression(const mongo::sbe::vm::CodeFragment *) Line 85	C++
       	db_sbe_test.exe!mongo::sbe::UnitTest_SuiteNameSBEBuiltinExtractSubArrayTestTestNameMemoryManagement::_doTest() Line 240	C++
      

            Assignee:
            zixuan.zhuang@mongodb.com Zixuan Zhuang
            Reporter:
            alberto.massari@mongodb.com Alberto Massari
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: