)]}'
{
  "commit": "bfea7d30591d2c8db0c51e89ee57b157ba339317",
  "tree": "6dca93bb1b4f4cc278bb0c3c47d3f7487a5ca618",
  "parents": [
    "c1a7d039587befeb01b5e13e23ef2e8ddc4df34f"
  ],
  "author": {
    "name": "Andrew Burgess",
    "email": "aburgess@redhat.com",
    "time": "Sun Sep 28 16:16:53 2025 +0100"
  },
  "committer": {
    "name": "Andrew Burgess",
    "email": "aburgess@redhat.com",
    "time": "Wed Oct 08 09:25:50 2025 +0100"
  },
  "message": "gdb: fix for \u0027set suppress-cli-notifications on\u0027 missed case\n\nI noticed this behaviour:\n\n  (gdb) info threads\n    Id   Target Id                               Frame\n    1    Thread 0xf7dbc700 (LWP 3161872) \"thr\" 0xf7eb2888 in clone () from /lib/libc.so.6\n  * 2    Thread 0xf7dbbb40 (LWP 3161884) \"thr\" breakpt () at thr.c:19\n  (gdb) set suppress-cli-notifications on\n  (gdb) thread 1\n  (gdb) thread 1\n  [Switching to thread 1 (Thread 0xf7dbc700 (LWP 3161872))]\n  #0  0xf7eb2888 in clone () from /lib/libc.so.6\n  (gdb)\n\nI think that the second \u0027thread 1\u0027 should not produce any output just\nlike the \u0027inferior\u0027 command, continuing in the same GDB session:\n\n  (gdb) inferior 1\n  (gdb)\n\nWithout suppress-cli-notifications we would see an inferior, thread,\nand frame being printed, but with suppress-cli-notifications set to\non, we get no output.\n\nThe difference in behaviours is that in inferior_command (inferior.c),\nwe always call notify_user_selected_context_changed, even in the case\nwhere the inferior doesn\u0027t actually change.\n\nIn thread_command (thread.c), we have some code that catches the\nthread not changed case, and calls print_selected_thread_frame.  The\nnotify_user_selected_context_changed function is only called if the\nthread actually changes.\n\nI did consider simply extending thread_command to check the global\ncli_suppress_notification.user_selected_context state and skipping the\ncall to print_selected_thread_frame if suppression is on.\n\nHowever, I realised that calling print_selected_thread_frame actually\nintroduces a bug.\n\nWhen the \u0027thread\u0027 command is used to select the currently selected\nthread, GDB still calls \u0027thread_selected\u0027.  And \u0027thread_select\u0027 always\nselects frame #0 within that thread, consider this session:\n\n  (gdb) info threads\n    Id   Target Id                              Frame\n    1    Thread 0xf7dbc700 (LWP 723986) \"thr\" 0xf7eb2888 in clone () from /lib/libc.so.6\n  * 2    Thread 0xf7dbbb40 (LWP 723990) \"thr\" breakpt () at thr.c:19\n  (gdb) bt\n  #0  breakpt () at thr.c:19\n  #1  0x080491fd in thread_worker (arg\u003d0xffff9514) at thr.c:31\n  #2  0xf7f7667e in start_thread () from /lib/libpthread.so.0\n  #3  0xf7eb289a in clone () from /lib/libc.so.6\n  (gdb) frame 3\n  #3  0xf7eb289a in clone () from /lib/libc.so.6\n  (gdb) thread 2\n  [Switching to thread 2 (Thread 0xf7dbbb40 (LWP 723990))]\n  #0  breakpt () at thr.c:19\n  19\t  while (stop)\n  (gdb) frame\n  #0  breakpt () at thr.c:19\n  19\t  while (stop)\n  (gdb)\n\nNotice that the frame resets back to frame #0.\n\nBy only calling print_selected_thread_frame, and not calling\nnotify_user_selected_context_changed, this means that GDB will fail to\nemit an MI async notification.  It is this async notification which\ntells MI consumers that the frame has been reset to #0.\n\nAnd so, I think that the correct solution is, like with the \u0027inferior\u0027\ncommand, to always call notify_user_selected_context_changed.\n\nThis does mean that in some cases unnecessary MI notifications can be\nemitted, however, an MI consumer should be able to handle these.  We\ncould try to avoid these, but we would need to extend thread_command\nto check that neither the thread OR frame has changed after the call\nto thread_select, and right now, I\u0027m not sure it\u0027s worth adding the\nextra complexity.\n\nI\u0027ve rewritten the gdb.base/cli-suppress-notification.exp test to\ncover more cases, especially the reselecting the same thread case.\nAnd I\u0027ve updated the gdb.mi/user-selected-context-sync.exp test to\nallow for the additional MI notifications that are emitted, and to\ncheck the frame reset case.\n\nWhile working on this change, I did wonder about calls to\nnotify_user_selected_context_changed for frame related commands.  In\nplaces we do elide calls to notify_user_selected_context_changed if\nthe frame hasn\u0027t changed.  I wondered if there were more bugs here?\n\nI don\u0027t think there are though.  While changing the inferior will also\nchange the selected thread, and the selected frame.  And changing the\nthread will also change the selected frame.  Changing the frame is the\n\"inner most\" context related thing that can be changed.  There are no\nside effect changes that also need to be notified, so for these cases,\nI think we are fine.\n\nAlso in infrun.c I fixed a code style issue relating to\nnotify_user_selected_context_changed.  It\u0027s not a functional change\nrequired by this commit, but it\u0027s related to this patch, so I\u0027m\nincluding it here.\n\nReviewed-By: Tankut Baris Aktemur \u003ctankut.baris.aktemur@intel.com\u003e\nTested-By: Tankut Baris Aktemur \u003ctankut.baris.aktemur@intel.com\u003e\nApproved-By: Tom Tromey \u003ctom@tromey.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "239ede968efb7a6d54c4ad75e88710fa665970fe",
      "old_mode": 33188,
      "old_path": "gdb/infrun.c",
      "new_id": "b3c408feb3043bc62becc7ae5bd9a6fdbb516729",
      "new_mode": 33188,
      "new_path": "gdb/infrun.c"
    },
    {
      "type": "modify",
      "old_id": "02e012f95645f32433abf33599bd41720ca7f19f",
      "old_mode": 33188,
      "old_path": "gdb/testsuite/gdb.base/cli-suppress-notification.c",
      "new_id": "12fe04c570842dbb584e886071ca415983be0823",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/cli-suppress-notification.c"
    },
    {
      "type": "modify",
      "old_id": "6880d983a4d9a3ae88f6f3e9e368103b5d8d32dd",
      "old_mode": 33188,
      "old_path": "gdb/testsuite/gdb.base/cli-suppress-notification.exp",
      "new_id": "003f7d247120c36464ae41a9f0a3d5a32cfa5202",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/cli-suppress-notification.exp"
    },
    {
      "type": "modify",
      "old_id": "c954057e90c4ce22e5b0dc2e97c92981750bdcc0",
      "old_mode": 33188,
      "old_path": "gdb/testsuite/gdb.mi/user-selected-context-sync.exp",
      "new_id": "8a4827fd4a80c92c94eb4f412d417e7bb73fdc6d",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.mi/user-selected-context-sync.exp"
    },
    {
      "type": "modify",
      "old_id": "1b855b4e0b3b302092092e75c4a1d43f754bc67c",
      "old_mode": 33188,
      "old_path": "gdb/thread.c",
      "new_id": "472f41969cfc71e685fb13e7e394d451cda0e546",
      "new_mode": 33188,
      "new_path": "gdb/thread.c"
    }
  ]
}
