)]}'
{
  "commit": "b4b3e2dee20dcde6eb47ebdc6231f5d8edf60ff5",
  "tree": "011709cafd49177bc49f47523f03ef3e772089f8",
  "parents": [
    "a2cf3633b33ec21b967f4c7ddfb7f1b80e676d2d"
  ],
  "author": {
    "name": "Andrew Burgess",
    "email": "andrew.burgess@embecosm.com",
    "time": "Thu Aug 29 12:37:00 2019 +0100"
  },
  "committer": {
    "name": "Andrew Burgess",
    "email": "andrew.burgess@embecosm.com",
    "time": "Tue Jun 01 09:23:34 2021 +0100"
  },
  "message": "gdb: avoid premature dummy frame garbage collection\n\nConsider the following chain of events:\n\n  * GDB is performing an inferior call, and\n\n  * the inferior calls longjmp, and\n\n  * GDB detects that the longjmp has completed, stops, and enters\n    check_longjmp_breakpoint_for_call_dummy (in breakpoint.c), and\n\n  * GDB tries to unwind the stack in order to check that the dummy\n    frame (setup for the inferior call) is still on the stack, but\n\n  * The unwind fails, possibly due to missing debug information, so\n\n  * GDB incorrectly concludes that the inferior has longjmp\u0027d past the\n    dummy frame, and so deletes the dummy frame, including the dummy\n    frame breakpoint, but then\n\n  * The inferior continues, and eventually returns to the dummy frame,\n    which is usually (always?) on the stack, the inferior starts\n    trying to execute the random contents of the stack, this results\n    in undefined behaviour.\n\nThis situation is already warned about in the comment on the function\ncheck_longjmp_breakpoint_for_call_dummy where we say:\n\n   You should call this function only at places where it is safe to currently\n   unwind the whole stack.  Failed stack unwind would discard live dummy\n   frames.\n\nThe warning here is fine, the problem is that, even though we call the\nfunction from a location within GDB where we hope to be able to\nunwind, sometime the state of the inferior means that the unwind will\nnot succeed.\n\nThis commit tries to improve the situation by adding the following\nadditional check; when GDB fails to find the dummy frame on the stack,\ninstead of just assuming that the dummy frame can be garbage\ncollected, first find the stop_reason for the last frame on the stack.\nIf this stop_reason indicates that the stack unwinding may have failed\nthen we assume that the dummy frame is still in use.  However, if the\nlast frame\u0027s stop_reason indicates that the stack unwind completed\nsuccessfully then we can be confident that the dummy frame is no\nlonger in use, and we garbage collect it.\n\nTested on x86-64 GNU/Linux.\n\ngdb/ChangeLog:\n\n\t* breakpoint.c (check_longjmp_breakpoint_for_call_dummy): Add\n\tcheck for why the backtrace stopped.\n\ngdb/testsuite/ChangeLog:\n\n\t* gdb.base/premature-dummy-frame-removal.c: New file.\n\t* gdb.base/premature-dummy-frame-removal.exp: New file.\n\t* gdb.base/premature-dummy-frame-removal.py: New file.\n\nChange-Id: I8f330cfe0f3f33beb3a52a36994094c4abada07e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "7581c0949df3cad9eca875f438a124efbe8944c7",
      "old_mode": 33188,
      "old_path": "gdb/ChangeLog",
      "new_id": "b6930dff39cd4e8859e41624271b468e347e1aa0",
      "new_mode": 33188,
      "new_path": "gdb/ChangeLog"
    },
    {
      "type": "modify",
      "old_id": "aa6b348dffde8a6b9d612c0604d248d13b491413",
      "old_mode": 33188,
      "old_path": "gdb/breakpoint.c",
      "new_id": "fb011fc1e0fc6839e8467626b5e2a8fcebc099a9",
      "new_mode": 33188,
      "new_path": "gdb/breakpoint.c"
    },
    {
      "type": "modify",
      "old_id": "e2a95d48c33e25f80038b36a219b99f8f8e6899c",
      "old_mode": 33188,
      "old_path": "gdb/testsuite/ChangeLog",
      "new_id": "6c7079325b95d9834f20b9bbdefc72b5c451f6a5",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/ChangeLog"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "32deefc962f38fa1a3d198b9e589276b05fbad26",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/premature-dummy-frame-removal.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "bf2a2a7975665135604bb406fc6e3138313b1a39",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "31936658788abe6cc3b9617ce2cdad3dcf671ca2",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/premature-dummy-frame-removal.py"
    }
  ]
}
