)]}'
{
  "commit": "43db8f70d86b2492b79f59342187b919fd58b3dd",
  "tree": "d1df0e5e6c93ed6f349728490de6117982206028",
  "parents": [
    "45cf0b829303f4604757fdd052bc95d589bac8c8"
  ],
  "author": {
    "name": "Andrew Burgess",
    "email": "aburgess@redhat.com",
    "time": "Thu Oct 23 16:34:20 2025 +0100"
  },
  "committer": {
    "name": "Andrew Burgess",
    "email": "aburgess@redhat.com",
    "time": "Mon Dec 08 13:33:51 2025 +0000"
  },
  "message": "gdbsupport: remove undefined behaviour from (forward_)scope_exit\n\nOur implementation of scope_exit and forward_scope_exit make use of\nthe Curiously Recurring Template Pattern (CRTP) to provide the\n\"release\" functionality, this is done in the scope_exit_base class in\nscope-exit.h.\n\nThe interesting (for this commit) parts of scope_exit_base look like\nthis:\n\n  template \u003ctypename CRTP\u003e\n  class scope_exit_base\n  {\n  public:\n    scope_exit_base () \u003d default;\n\n    ~scope_exit_base ()\n    {\n      if (!m_released)\n        {\n  \tauto *self \u003d static_cast\u003cCRTP *\u003e (this);\n  \tself-\u003eon_exit ();\n        }\n    }\n\n    ... snip ...\n  };\n\nBy the time ~scope_exit_base is called the destructor for the derived\nclass (called CRTP here) has already been run, which means any data\nmembers in the derived class will have also have had their destructors\nrun.  As a result of this I believe that casting \u0027this\u0027 to the derived\ntype, and then calling the on_exit method is undefined behaviour, as\n\u0027this\u0027 can no longer be considered a valid instance of CRTP (the CRTP\npart has been destructed).\n\nIn reality, the memory for the derived type is not reclaimed until\nafter ~scope_exit_base has finished, so as long as the data members of\nthe derived type are Plain Old Data (POD), then the current code\nshould be just fine; any data members of the derived class will remain\nin place, and untouched, until ~scope_exit_base has completed.\n\nBut still, I don\u0027t think we should rely on undefined behaviour.\n\nI actually ran into this when, in another series, I tried to reuse\nscope_exit_base with a class where a data member was not POD, and in\nthis case GDB would crash because my new on_exit function was making\nuse of the non-POD data member after it had been destructed, and\nresources released.\n\nI propose that we move away from the CRTP, and instead flip the class\nhierarchy.  Instead of derived classes like scope_exit inheriting from\nscope_exit_base, scope_exit_base should inherit from scope_exit.\n\nWhat this means, is that when ~scope_exit_base is called, ~scope_exit\nwill not yet have been run, and the data members of scope_exit will\nstill be valid.\n\nTo allow the existing names to be used, the plan is that the existing\nscope_exit and forward_scope_exit classes are renamed to\nscope_exit_policy and forward_scope_exit_policy.  These policy classes\nwill then be injected via a template argument as the base class for\nscope_exit_base.  Finally, we can:\n\n  template\u003ctypename EF\u003e\n  using scope_exit \u003d scope_exit_base\u003cscope_exit_policy\u003cEF\u003e\u003e;\n\nwhich defines the scope_exit type.  This type is a drop in replacement\nwith all of GDB\u0027s existing code, but avoids the undefined behaviour.\nWe can do something similar with forward_scope_exit.\n\nThere should be no user visible changes after this commit.\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "040a1616bfef31a6ac210e72060d2a7d6acf444b",
      "old_mode": 33188,
      "old_path": "gdbsupport/forward-scope-exit.h",
      "new_id": "fd93374afc97f5cbd7729fb5be1cedac3b7e55fe",
      "new_mode": 33188,
      "new_path": "gdbsupport/forward-scope-exit.h"
    },
    {
      "type": "modify",
      "old_id": "6a550c5d4c0d03c84a52d5f9f93c1494c9cee85a",
      "old_mode": 33188,
      "old_path": "gdbsupport/scope-exit.h",
      "new_id": "b61535dfadfd38b3d2ad449dd5793aefd0be28eb",
      "new_mode": 33188,
      "new_path": "gdbsupport/scope-exit.h"
    }
  ]
}
