)]}'
{
  "commit": "e5501dd4321a6b63f306b292347e5d22058c3ed2",
  "tree": "998b9c50070f28c6101d8326f7a3b2a3ab854d1a",
  "parents": [
    "b425859021d17adf62f06fb904797cf8642986ad"
  ],
  "author": {
    "name": "Kevin Buettner",
    "email": "kevinb@redhat.com",
    "time": "Wed Feb 05 11:27:00 2025 -0700"
  },
  "committer": {
    "name": "Kevin Buettner",
    "email": "kevinb@redhat.com",
    "time": "Wed Feb 05 11:28:29 2025 -0700"
  },
  "message": "Make linux checkpoints work with multiple inferiors\n\nThe current linux checkpoint code, most of which may be found in\nlinux-fork.c, is quite broken when attempting to use more than\none inferior.  Running GDB will show internal errors when starting\ntwo inferiors, placing a checkpoint in one, then switching to\nthe other and doing one of the following commands, \"restart\",\n\"detach\", \"kill\", or continue (to program exit).  Test cases\nfor two of those scenarios may be found in this bug:\n\n    https://sourceware.org/bugzilla/show_bug.cgi?id\u003d31065\n\nI\u0027ve tested for each of the scenarios and many more in the new\ntest case, gdb.multi/checkpoint-multi.exp.\n\nI started off with the goal of fixing just those problems, and was\nmostly successful with a much smaller patch, but doing \"info\ncheckpoints\" with more than one inferior didn\u0027t work correctly due to\nsome of the inferiors being in the wrong program space.  That led me\nto making the linux-fork code fully inferior-aware.\n\nPrior to this commit, the list of forks was being maintained in a\nglobal named named \u0027fork_list\u0027.  I turned this into a per-inferior\ndata structure.  There was also global named \u0027highest_fork_num\u0027 which\nis also now part of the per-inferior struct.  A registry key named\n\u0027checkpoint_inferior_data_key\u0027 along with function\n\u0027get_checkpoint_inferior_data\u0027 is used to access the per-inferior\ndata.  This new function, get_checkpoint_inferior_data, is only\ncalled by the new functions \u0027fork_list\u0027, \u0027reset_highest_fork_num\u0027,\nand increment_highest_fork_num, each of which is passed a pointer to\nthe inferior.  Most occurrences referring to the (previously) global\n\u0027fork_list\u0027 have been replaced by \u0027fork_list (inf)\u0027.  In some\nfunctions, where the \u0027fork_list\u0027 is referenced multiple times, a local\nnamed \u0027fork_list\u0027 is declared and initialized instead, like this:\n\n    auto \u0026fork_list \u003d ::fork_list (inf);\n\nThe constructor for \u0027struct fork_info\u0027 has gained an additional\nparameter.  In addition to passing the pid of the new fork, we now\nalso pass the fork identifier, fork_num, to the constructor.  This\ninteger is shown to the user in the \"info checkpoints\" command and\nis provided by the user, perhaps in conjunction with the inferior\nnumber, in commands which manipulate checkpoints, e.g. \u0027restart\u0027 and\n\u0027delete checkpoint\u0027.\n\nWhen checkpoints are used in only one inferior, this commit will\npresent information to the user and will accept checkpoint identifiers\nto commands in much the same way as the code did before this commit.\nPer Pedro Alves\u0027s recommendations, the \"info checkpoints\" command has\nbeen changed somewhat.  \"info checkpoints\" used to display \"(main\nprocess)\" for the first process in the checkpoint list.  This is no\nlonger done because it does not provide useful information.  It also\nused to display \"\u003crunning\u003e\", when the process is running and no useful\nframe information may be displayed.  This has been changed to\n\"(running)\" in order to be more consistent with the output of the\n\"info threads\" command.  A new column has been added to the output for\nshowing the active process in the output from \"info checkpoints\".\nThis column will display \u0027y\u0027 for the active process and \u0027n\u0027 for the\nothers.  For the active inferior a \u0027*\u0027 is also printed preceding the\ncheckpoint identifier.  Here\u0027s what things look(ed) like before and\nafter for just one inferior:\n\nBefore:\n\n(gdb) info checkpoints\n* 0 Thread 0x7ffff7cd3740 (LWP 84201) (main process) at 0x40114a, file hello.c, line 28\n  1 process 84205 at 0x401199, file hello.c, line 51\n  2 process 84206 at 0x4011a3, file hello.c, line 53\n\nAfter:\n\n(gdb) info checkpoints\n  Id Active Target Id      Frame\n*  0 y      process 551311 at 0x40114a, file hello.c, line 28\n   1 n      process 551314 at 0x401199, file hello.c, line 51\n   2 n      process 551315 at 0x4011a3, file hello.c, line 53\n\n(The Thread versus process distinction is handled by another\npatch - the \"After\" example assumes that patch is applied too.)\n\nWhen there are multiple inferiors, the \"info checkpoints\" output looks\nlike this:\n\n(gdb) info checkpoints\n  Id  Active Target Id      Frame\n  1.0 y      process 535276 at 0x401199, file hello.c, line 51\n  1.1 n      process 535283 at 0x401199, file hello.c, line 51\n  1.2 n      process 535288 at 0x401199, file hello.c, line 51\n  2.1 n      process 535280 at 0x401258, file goodbye.c, line 62\n  2.2 y      process 535284 at 0x401258, file goodbye.c, line 62\n* 3.0 y      process 535285 at 0x40115c, file hangout.c, line 31\n  3.2 n      process 535287 at 0x40115c, file hangout.c, line 31\n\nA new function named \u0027parse_checkpoint_id\u0027 has been added.  As its\nname suggests, it\u0027s responsible for parsing a string representing a\ncheckpoint identifier.  These identifiers may be either a decimal\nnumber representing the checkpoint number in the current inferior or\ntwo decimal numbers separated by \u0027.\u0027, in which case the first is the\ninferior number and the second is the checkpoint number in that\ninferior.  It is called by delete_checkpoint_command,\ndetach_checkpoint_command, info_checkpoints_command, and\nrestart_command.  Calls to \u0027parse_checkpoint_id\u0027 replace calls to\n\u0027parse_and_eval_long\u0027, plus error checking and error reporting code\nnear the calls to \u0027parse_and_eval_long\u0027.  As such, error checking and\nreporting has been consolidated into a single function and the\nmessages output are more uniform, though this has necessitated changes\nto the existing test case gdb.base/checkpoint.exp.\n\nThe functions \u0027find_fork_ptid\u0027 and \u0027find_fork_pid\u0027 used to return a\npointer to a fork_info struct.  They now return a pair consisting of\nthe pointer to a fork_info struct in addition to a pointer to the\ninferior containing that checkpoint.\n\n\u0027find_fork_id\u0027 returns a pointer to a fork_info struct just as it did\nbefore, but it\u0027s now gained a new parameter, \u0027inf\u0027, which is the\ninferior in which to look.\n\ninfo_checkpoints_command used to simply iterate over the list of\nforks (checkpoints), printing each one out.  It now needs to iterate\nover all inferiors and, for those which have checkpoints, it needs\nto iterate over the list of checkpoints in that inferior.  As noted\nearlier, the format of the output has been changed so that checkpoint\nidentifiers incorporating an inferior number may be printed.\n\nlinux_fork_context, called by restart_command, now contains code to\nswitch inferiors when the fork being restarted is in an inferior which\nis different from the current one.  The scoped_switch_fork_info class\nnow also contains code for switching inferiors in both the constructor\nand destructor.\n\ngdb/linux-nat.c has a few changes.  All but one of them are related\nto passing the inferior to one of the linux-fork functions.  But\none of the tests in linux_nat_target::detach has also changed in\na non-obvious way.  In attempting to determine whether to call\nlinux_fork_detach(), that code used to do:\n\n  if (pid \u003d\u003d inferior_ptid.pid () \u0026\u0026 forks_exist_p ())\n\nIt\u0027s been simplified to:\n\n  if (forks_exist_p (inf))\n\nI had added the \u0027pid \u003d\u003d inferior_ptid.pid ()\u0027 condition in late 2023\nwhile working on a detach bug.  It was kind of a hack to prevent\ncalling linux_fork_detach() when in a different inferior.  That\u0027s no\nlonger needed since the call to forks_exist_p does this directly -\ni.e. it is now inferior-aware.\n\nFinally, the header file \u0027linux-fork.h\u0027 has been updated to reflect\nthe fact that add_fork, linux_fork_killall, linux_fork_detach, and\nforks_exist_p all now require that a pointer to an inferior be passed\nto these functions.  Additionally (as mentioned earlier),\nfind_fork_pid now returns std::pair\u003cfork_info *, inferior *\u003e instead\n\u0027of fork_info *\u0027.\n\nBug: https://sourceware.org/bugzilla/show_bug.cgi?id\u003d31065\nReviewed-By: Tom Tromey \u003ctom@tromey.com\u003e\nApproved-By: Andrew Burgess \u003caburgess@redhat.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "7d3505b59486e400d0dca87832e1edeb194aae22",
      "old_mode": 33188,
      "old_path": "gdb/linux-fork.c",
      "new_id": "585474fdfedcce07e375ce6a8436f1cc73d94c46",
      "new_mode": 33188,
      "new_path": "gdb/linux-fork.c"
    },
    {
      "type": "modify",
      "old_id": "2a306881695ee917fabcdedb07c608aaa36a3869",
      "old_mode": 33188,
      "old_path": "gdb/linux-fork.h",
      "new_id": "c3b403bb60a842937d841ca21459bb0af4239e94",
      "new_mode": 33188,
      "new_path": "gdb/linux-fork.h"
    },
    {
      "type": "modify",
      "old_id": "3f252370c7b275b80e01848b190d7c48246fd25a",
      "old_mode": 33188,
      "old_path": "gdb/linux-nat.c",
      "new_id": "b16f9f967266ee18fcb1751f549ffb817d5bec7f",
      "new_mode": 33188,
      "new_path": "gdb/linux-nat.c"
    },
    {
      "type": "modify",
      "old_id": "31b5a13bb8f94a5ac2b7eafa10407ff5fd985925",
      "old_mode": 33188,
      "old_path": "gdb/testsuite/gdb.base/checkpoint.exp",
      "new_id": "4a8a9a8eb7f81b54521cd4b69b324ca1c37cc8c4",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.base/checkpoint.exp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "2bd654347b0a31d88912e273a6f09b76cc2ce457",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.multi/checkpoint-multi.exp"
    }
  ]
}
