)]}'
{
  "commit": "ac13143d96b61cec419b49f76e58d2045aba8536",
  "tree": "2c6d49388d943d89eab84f631b7487973ff6fb4a",
  "parents": [
    "82a89508915e7607e10675ee5a4dacd8fc72c649"
  ],
  "author": {
    "name": "Tejas Anil Nagmote",
    "email": "tejasnagmote520@gmail.com",
    "time": "Mon Sep 21 15:54:59 2026 +0530"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon Sep 21 11:24:59 2026 +0100"
  },
  "message": "Diagnose invalid PauseTiming()/ResumeTiming() calls (#2235) (#2274)\n\n* Move the PauseTiming()/ResumeTiming() assertions to the caller (#2235)\n\nCalling PauseTiming() outside the benchmark loop stops a timer that was never\nstarted, so StopTimer() adds `ChronoClockNow() - 0` to the run\u0027s real time --\nan absolute clock reading, not a duration. The same happens to the CPU time.\nThat is the ~86 s offset in #2235, and why every later benchmark in the\nprocess reports a bigger number.\n\nThe precondition is already checked. The problem is where: BM_CHECK is\ncompiled into the library, so it only fires if the library was built with\nassertions. Distributions ship a release build, and then the check is gone no\nmatter how the benchmark itself was compiled.\n\nMove it. PauseTiming() and ResumeTiming() become inline wrappers in state.h\nthat assert and call PauseTimingImpl()/ResumeTimingImpl(), which hold the\nexisting bodies. The condition is the same and the runtime behaviour is the\nsame; the assertion now follows the NDEBUG of whoever writes the benchmark,\nand disappears once they define it.\n\ndiagnostics_test caught what BM_CHECK threw through the library\u0027s abort\nhandler. A plain assert() does not use that handler, so the test becomes\ndiagnostics_gtest with ASSERT_DEATH_IF_SUPPORTED, like min_time_parse_gtest\nand profiler_manager_gtest. It covers pause and resume before and after the\nloop, and checks that a run which is not diagnosed still reports a real and\nCPU time below a second.\n\n* Rewrite death tests\n\n* Force-inline PauseTiming()/ResumeTiming() for MSVC shared builds\n\nState is BENCHMARK_EXPORT, so a program linking the shared library sees\nit as __declspec(dllimport). MSVC does not expand these two inline\nwrappers at the call site; it calls the copies exported from\nbenchmark.dll instead, and those were compiled with the library\u0027s\nNDEBUG. In Release/shared the assertion is therefore gone, which is why\ndiagnostics_gtest failed to die on exactly the two windows *.Release.shared\njobs while static and Debug builds passed. (A Debug DLL keeps its\nasserts, so the same call into the DLL still fires there.)\n\nAn inline dllimport member without the assert is expanded normally; it\nis the body with assert() that MSVC declines to inline. Marking the\nwrappers BENCHMARK_ALWAYS_INLINE (__forceinline on MSVC), as begin() and\nend() already are, puts the check back in the caller\u0027s translation unit.\n\nChecked on MSVC 19.40 and 19.latest x64: at /O2 and /O2 /Ob1 the caller\nnow contains the _wassert call and a tail call to PauseTimingImpl(); with\nNDEBUG only the tail call remains. No C4714 at /W4 /WX.\n\n* Move the PauseTiming()/ResumeTiming() tests into benchmark_gtest\n\nAs asked in review, the tests now live in the existing benchmark_gtest.cc\ninstead of a new diagnostics_gtest.cc. Only the suite names changed.\n\n* Drop issue reference from timing test comment\n\n* Reword the PauseTiming()/ResumeTiming() docs note\n\nUse the wording suggested in review: state the precondition for each\ncall directly rather than describing the failure mode, and note that\ninvalid calls are diagnosed when user code is built without NDEBUG.\n\n---------\n\nCo-authored-by: Roman Lebedev \u003clebedev.ri@gmail.com\u003e\nCo-authored-by: dominic \u003c510002+dmah42@users.noreply.github.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "30f3608dea33434ba010274d74636454c558d5d7",
      "old_mode": 33188,
      "old_path": "docs/user_guide.md",
      "new_id": "5848b6572507ecb6ba8a970e86381e45834ce513",
      "new_mode": 33188,
      "new_path": "docs/user_guide.md"
    },
    {
      "type": "modify",
      "old_id": "356c5509a0a2d0b2c00eb6a9431d3f9254640a8d",
      "old_mode": 33188,
      "old_path": "include/benchmark/state.h",
      "new_id": "86009e22dfd61aa9fef02d5d7646d7f6a7d54b19",
      "new_mode": 33188,
      "new_path": "include/benchmark/state.h"
    },
    {
      "type": "modify",
      "old_id": "9388e342eba7dc586f69f00496e710f1a48963f2",
      "old_mode": 33188,
      "old_path": "src/benchmark.cc",
      "new_id": "5d1e7e975337ae937daf6577e9014f5c897c0410",
      "new_mode": 33188,
      "new_path": "src/benchmark.cc"
    },
    {
      "type": "modify",
      "old_id": "4384c30ec98b1d33b1afb8ed6cb6b270fefdf09d",
      "old_mode": 33188,
      "old_path": "test/CMakeLists.txt",
      "new_id": "e9edd426520834d2fbe6932423c74fd0262f148e",
      "new_mode": 33188,
      "new_path": "test/CMakeLists.txt"
    },
    {
      "type": "modify",
      "old_id": "09d7c80a25ff5e56e94609dd8e535f873e1869ae",
      "old_mode": 33188,
      "old_path": "test/benchmark_gtest.cc",
      "new_id": "bd6304ade2a8ae3fbefd93e2b5f77b9cba104302",
      "new_mode": 33188,
      "new_path": "test/benchmark_gtest.cc"
    },
    {
      "type": "delete",
      "old_id": "a79e49f49cc9e6ff7784f316f94fa0fc046a08f0",
      "old_mode": 33188,
      "old_path": "test/diagnostics_test.cc",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    }
  ]
}
