tst-makecontext.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* Copyright (C) 2006-2019 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library 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 GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <errno.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <ucontext.h>
  18. #include <assert.h>
  19. #include <unwind.h>
  20. #include <dlfcn.h>
  21. #include <gnu/lib-names.h>
  22. ucontext_t ucp;
  23. char st1[16384];
  24. __thread int thr;
  25. int somevar = -76;
  26. long othervar = -78L;
  27. struct trace_arg
  28. {
  29. int cnt, size;
  30. };
  31. static _Unwind_Reason_Code
  32. backtrace_helper (struct _Unwind_Context *ctx, void *a)
  33. {
  34. struct trace_arg *arg = a;
  35. if (++arg->cnt == arg->size)
  36. return _URC_END_OF_STACK;
  37. return _URC_NO_REASON;
  38. }
  39. void
  40. cf (int i)
  41. {
  42. struct trace_arg arg = { .size = 100, .cnt = -1 };
  43. void *handle;
  44. _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
  45. if (i != othervar || thr != 94)
  46. {
  47. printf ("i %d thr %d\n", i, thr);
  48. exit (1);
  49. }
  50. /* Test if callback function of _Unwind_Backtrace is not called infinitely
  51. times. See Bug 18508 or gcc bug "Bug 66303 - runtime.Caller() returns
  52. infinitely deep stack frames on s390x.".
  53. The go runtime calls backtrace_full() in
  54. <gcc-src>/libbacktrace/backtrace.c, which uses _Unwind_Backtrace(). */
  55. handle = dlopen (LIBGCC_S_SO, RTLD_LAZY);
  56. if (handle != NULL)
  57. {
  58. unwind_backtrace = dlsym (handle, "_Unwind_Backtrace");
  59. if (unwind_backtrace != NULL)
  60. {
  61. unwind_backtrace (backtrace_helper, &arg);
  62. assert (arg.cnt != -1 && arg.cnt < 100);
  63. }
  64. dlclose (handle);
  65. }
  66. /* Since uc_link below has been set to NULL, setcontext is supposed to
  67. terminate the process normally after this function returns. */
  68. }
  69. int
  70. do_test (void)
  71. {
  72. if (getcontext (&ucp) != 0)
  73. {
  74. if (errno == ENOSYS)
  75. {
  76. puts ("context handling not supported");
  77. return 0;
  78. }
  79. puts ("getcontext failed");
  80. return 1;
  81. }
  82. thr = 94;
  83. ucp.uc_link = NULL;
  84. ucp.uc_stack.ss_sp = st1;
  85. ucp.uc_stack.ss_size = sizeof st1;
  86. makecontext (&ucp, (void (*) (void)) cf, 1, somevar - 2);
  87. if (setcontext (&ucp) != 0)
  88. {
  89. puts ("setcontext failed");
  90. return 1;
  91. }
  92. return 2;
  93. }
  94. #define TEST_FUNCTION do_test ()
  95. #include "../test-skeleton.c"