detach-step-over.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* This testcase is part of GDB, the GNU debugger.
  2. Copyright 2021-2022 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #define _GNU_SOURCE
  14. #include <assert.h>
  15. #include <pthread.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <string.h>
  20. #include <signal.h>
  21. /* Number of threads we'll create. */
  22. int n_threads = 10;
  23. int mypid;
  24. static void
  25. setup_done (void)
  26. {
  27. }
  28. /* Entry point for threads. Loops forever. */
  29. void *
  30. thread_func (void *arg)
  31. {
  32. /* Avoid setting the breakpoint at an instruction that wouldn't
  33. require a fixup phase, like a branch/jump. In such a case, even
  34. if GDB manages to detach the inferior with an incomplete
  35. displaced step, GDB inferior may still not crash. A breakpoint
  36. at a line that increments a variable is good bet that we end up
  37. setting a breakpoint at an instruction that will require a fixup
  38. phase to move the PC from the scratch pad to the instruction
  39. after the breakpoint. */
  40. volatile unsigned counter = 0;
  41. while (1)
  42. {
  43. counter++; /* Set breakpoint here. */
  44. counter++;
  45. counter++;
  46. }
  47. return NULL;
  48. }
  49. /* Allow for as much timeout as DejaGnu wants, plus a bit of
  50. slack. */
  51. #define SECONDS (TIMEOUT + 20)
  52. /* We'll exit after this many seconds. */
  53. unsigned int seconds_left = SECONDS;
  54. /* GDB sets this whenever it's about to start a new detach/attach
  55. sequence. We react by resetting the seconds-left counter. */
  56. volatile int again = 0;
  57. int
  58. main (int argc, char **argv)
  59. {
  60. int i;
  61. signal (SIGUSR1, SIG_IGN);
  62. mypid = getpid ();
  63. setup_done ();
  64. if (argc > 1)
  65. n_threads = atoi (argv[1]);
  66. /* Spawn the test threads. */
  67. for (i = 0; i < n_threads; ++i)
  68. {
  69. pthread_t child;
  70. int rc;
  71. rc = pthread_create (&child, NULL, thread_func, NULL);
  72. assert (rc == 0);
  73. }
  74. /* Exit after a while if GDB is gone/crashes. But wait long enough
  75. for one attach/detach sequence done by the .exp file. */
  76. while (--seconds_left > 0)
  77. {
  78. sleep (1);
  79. if (again)
  80. {
  81. /* GDB should be reattaching soon. Restart the timer. */
  82. again = 0;
  83. seconds_left = SECONDS;
  84. }
  85. }
  86. printf ("timeout, exiting\n");
  87. return 0;
  88. }