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

PlanRanker::scoreTree may divide by zero

    • Fully Compatible
    • ALL
    • Hide

      Need to run under UBSAN which isn't documented how to do yet, but should be easy enough to make it a hard error by adding an invariant that the denominator is non-zero.

      Show
      Need to run under UBSAN which isn't documented how to do yet, but should be easy enough to make it a hard error by adding an invariant that the denominator is non-zero.
    • Query 10 (02/22/16)

      The all.js test appears to trigger this, and UBSAN complains about it:

      [executor:js_test:job0] 2016-02-16T19:22:21.175-0500 Running all.js...
      ./mongo --eval MongoRunner.dataDir = "/data/db/job0/mongorunner"; TestData = new Object(); TestData.wiredTigerEngineConfigString = ""; TestData.maxPort = 20249; TestData.wiredTigerIndexConfigString = ""; TestData.noJournal = false; TestData.testName = "all"; TestData.storageEngine = ""; TestData.minPort = 20010; TestData.noJournalPrealloc = true; TestData.wiredTigerCollectionConfigString = ""; MongoRunner.dataPath = "/data/db/job0/mongorunner/" --readMode commands --port 20000 jstests/core/all.js
      [js_test:all] 2016-02-16T19:22:21.176-0500 Starting JSTest jstests/core/all.js...
      ./mongo --eval MongoRunner.dataDir = "/data/db/job0/mongorunner"; TestData = new Object(); TestData.wiredTigerEngineConfigString = ""; TestData.maxPort = 20249; TestData.wiredTigerIndexConfigString = ""; TestData.noJournal = false; TestData.testName = "all"; TestData.storageEngine = ""; TestData.minPort = 20010; TestData.noJournalPrealloc = true; TestData.wiredTigerCollectionConfigString = ""; MongoRunner.dataPath = "/data/db/job0/mongorunner/" --readMode commands --port 20000 jstests/core/all.js
      [js_test:all] 2016-02-16T19:22:21.182-0500 JSTest jstests/core/all.js started with pid 25729.
      [js_test:all] 2016-02-16T19:22:21.208-0500 MongoDB shell version: 0.0.0
      [js_test:all] 2016-02-16T19:22:21.354-0500 connecting to: 127.0.0.1:20000/test
      [MongoDFixture:job0] 2016-02-16T19:22:21.355-0500 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:57448 #2 (1 connection now open)
      [js_test:all] 2016-02-16T19:22:21.357-0500 /data/db/job0/mongorunner/
      [MongoDFixture:job0] 2016-02-16T19:22:21.358-0500 I COMMAND  [conn2] CMD: drop test.jstests_all
      [MongoDFixture:job0] 2016-02-16T19:22:21.451-0500 I COMMAND  [conn2] CMD: drop test.jstests_all
      [MongoDFixture:job0] 2016-02-16T19:22:21.475-0500 I INDEX    [conn2] build index on: test.jstests_all properties: { v: 1, key: { a: 1.0 }, name: "a_1", ns: "test.jstests_all" }
      [MongoDFixture:job0] 2016-02-16T19:22:21.475-0500 I INDEX    [conn2] 	 building index using bulk method
      [MongoDFixture:job0] 2016-02-16T19:22:21.476-0500 I INDEX    [conn2] build index done.  scanned 0 total records. 0 secs
      [MongoDFixture:job0] src/mongo/db/query/plan_ranker.cpp:203:53: runtime error: division by zero
      [MongoDFixture:job0]     #0 0x20008d5 in mongo::PlanRanker::scoreTree(mongo::PlanStageStats const*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/query/plan_ranker.cpp:203:9
      [MongoDFixture:job0]     #1 0x19af87e in mongo::CachedPlanStage::updatePlanCache() /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/exec/cached_plan.cpp:330:23
      [MongoDFixture:job0]     #2 0x19ad687 in mongo::CachedPlanStage::pickBestPlan(mongo::PlanYieldPolicy*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/exec/cached_plan.cpp:113:13
      [MongoDFixture:job0]     #3 0x1ff4c0a in mongo::PlanExecutor::pickBestPlan(mongo::PlanExecutor::YieldPolicy) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/query/plan_executor.cpp:206:16
      [MongoDFixture:job0]     #4 0x1ff3e7e in mongo::PlanExecutor::make(mongo::OperationContext*, std::unique_ptr<mongo::WorkingSet, std::default_delete<mongo::WorkingSet> >, std::unique_ptr<mongo::PlanStage, std::default_delete<mongo::PlanStage> >, std::unique_ptr<mongo::QuerySolution, std::default_delete<mongo::QuerySolution> >, std::unique_ptr<mongo::CanonicalQuery, std::default_delete<mongo::CanonicalQuery> >, mongo::Collection const*, std::string const&, mongo::PlanExecutor::YieldPolicy) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/query/plan_executor.cpp:143:21
      [MongoDFixture:job0]     #5 0x1ff4678 in mongo::PlanExecutor::make(mongo::OperationContext*, std::unique_ptr<mongo::WorkingSet, std::default_delete<mongo::WorkingSet> >, std::unique_ptr<mongo::PlanStage, std::default_delete<mongo::PlanStage> >, std::unique_ptr<mongo::QuerySolution, std::default_delete<mongo::QuerySolution> >, std::unique_ptr<mongo::CanonicalQuery, std::default_delete<mongo::CanonicalQuery> >, mongo::Collection const*, mongo::PlanExecutor::YieldPolicy) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/query/plan_executor.cpp:120:12
      [MongoDFixture:job0]     #6 0x1f6245b in mongo::getExecutorCount(mongo::OperationContext*, mongo::Collection*, mongo::CountRequest const&, bool, mongo::PlanExecutor::YieldPolicy) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/query/get_executor.cpp:1214:12
      [MongoDFixture:job0]     #7 0x17e3248 in mongo::(anonymous namespace)::CmdCount::run(mongo::OperationContext*, std::string const&, mongo::BSONObj&, int, std::string&, mongo::BSONObjBuilder&) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands/count_cmd.cpp:140:39
      [MongoDFixture:job0]     #8 0x195711b in mongo::Command::run(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/dbcommands.cpp:1464:19
      [MongoDFixture:job0]     #9 0x1955710 in mongo::Command::execCommand(mongo::OperationContext*, mongo::Command*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/dbcommands.cpp:1332:18
      [MongoDFixture:job0]     #10 0x17cd335 in mongo::runCommands(mongo::OperationContext*, mongo::rpc::RequestInterface const&, mongo::rpc::ReplyBuilderInterface*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/commands.cpp:498:9
      [MongoDFixture:job0]     #11 0x1c748f2 in mongo::(anonymous namespace)::receivedRpc(mongo::OperationContext*, mongo::Client&, mongo::DbResponse&, mongo::Message&) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/instance.cpp:304:9
      [MongoDFixture:job0]     #12 0x1c748f2 in mongo::assembleResponse(mongo::OperationContext*, mongo::Message&, mongo::DbResponse&, mongo::HostAndPort const&) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/instance.cpp:525
      [MongoDFixture:job0]     #13 0x143d1af in mongo::MyMessageHandler::process(mongo::Message&, mongo::AbstractMessagingPort*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/db/db.cpp:173:17
      [MongoDFixture:job0]     #14 0x2b75d52 in mongo::PortMessageServer::handleIncomingMsg(void*) /home/andrew/Documents/10gen/dev/src/mongodb/src/mongo/util/net/message_server_port.cpp:229:17
      [MongoDFixture:job0]     #15 0x7f72dd4896a9 in start_thread /build/buildd/glibc-2.21/nptl/pthread_create.c:333
      [MongoDFixture:job0]     #16 0x7f72dcfa7eec in clone /build/buildd/glibc-2.21/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:109
      

      Note that while IEEE may specify that division by 0 results in NaN, the C++ standard declares it to be undefined behavior.

      The relevant snippet of code in plan_ranker.cpp:

      https://github.com/mongodb/mongo/blob/master/src/mongo/db/query/plan_ranker.cpp#L198-L203

      If the 'work' field is zero, this will definitely cause a division by zero.

            Assignee:
            tess.avitabile@mongodb.com Tess Avitabile (Inactive)
            Reporter:
            andrew.morrow@mongodb.com Andrew Morrow (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: