uprobe_multi.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdbool.h>
  5. #include <stdint.h>
  6. #include <sys/mman.h>
  7. #include <unistd.h>
  8. #include <sdt.h>
  9. #ifndef MADV_POPULATE_READ
  10. #define MADV_POPULATE_READ 22
  11. #endif
  12. #ifndef MADV_PAGEOUT
  13. #define MADV_PAGEOUT 21
  14. #endif
  15. int __attribute__((weak)) uprobe(void)
  16. {
  17. return 0;
  18. }
  19. #define __PASTE(a, b) a##b
  20. #define PASTE(a, b) __PASTE(a, b)
  21. #define NAME(name, idx) PASTE(name, idx)
  22. #define DEF(name, idx) int __attribute__((weak)) NAME(name, idx)(void) { return 0; }
  23. #define CALL(name, idx) NAME(name, idx)();
  24. #define F(body, name, idx) body(name, idx)
  25. #define F10(body, name, idx) \
  26. F(body, PASTE(name, idx), 0) F(body, PASTE(name, idx), 1) F(body, PASTE(name, idx), 2) \
  27. F(body, PASTE(name, idx), 3) F(body, PASTE(name, idx), 4) F(body, PASTE(name, idx), 5) \
  28. F(body, PASTE(name, idx), 6) F(body, PASTE(name, idx), 7) F(body, PASTE(name, idx), 8) \
  29. F(body, PASTE(name, idx), 9)
  30. #define F100(body, name, idx) \
  31. F10(body, PASTE(name, idx), 0) F10(body, PASTE(name, idx), 1) F10(body, PASTE(name, idx), 2) \
  32. F10(body, PASTE(name, idx), 3) F10(body, PASTE(name, idx), 4) F10(body, PASTE(name, idx), 5) \
  33. F10(body, PASTE(name, idx), 6) F10(body, PASTE(name, idx), 7) F10(body, PASTE(name, idx), 8) \
  34. F10(body, PASTE(name, idx), 9)
  35. #define F1000(body, name, idx) \
  36. F100(body, PASTE(name, idx), 0) F100(body, PASTE(name, idx), 1) F100(body, PASTE(name, idx), 2) \
  37. F100(body, PASTE(name, idx), 3) F100(body, PASTE(name, idx), 4) F100(body, PASTE(name, idx), 5) \
  38. F100(body, PASTE(name, idx), 6) F100(body, PASTE(name, idx), 7) F100(body, PASTE(name, idx), 8) \
  39. F100(body, PASTE(name, idx), 9)
  40. #define F10000(body, name, idx) \
  41. F1000(body, PASTE(name, idx), 0) F1000(body, PASTE(name, idx), 1) F1000(body, PASTE(name, idx), 2) \
  42. F1000(body, PASTE(name, idx), 3) F1000(body, PASTE(name, idx), 4) F1000(body, PASTE(name, idx), 5) \
  43. F1000(body, PASTE(name, idx), 6) F1000(body, PASTE(name, idx), 7) F1000(body, PASTE(name, idx), 8) \
  44. F1000(body, PASTE(name, idx), 9)
  45. F10000(DEF, uprobe_multi_func_, 0)
  46. F10000(DEF, uprobe_multi_func_, 1)
  47. F10000(DEF, uprobe_multi_func_, 2)
  48. F10000(DEF, uprobe_multi_func_, 3)
  49. F10000(DEF, uprobe_multi_func_, 4)
  50. static int bench(void)
  51. {
  52. F10000(CALL, uprobe_multi_func_, 0)
  53. F10000(CALL, uprobe_multi_func_, 1)
  54. F10000(CALL, uprobe_multi_func_, 2)
  55. F10000(CALL, uprobe_multi_func_, 3)
  56. F10000(CALL, uprobe_multi_func_, 4)
  57. return 0;
  58. }
  59. #define PROBE STAP_PROBE(test, usdt);
  60. #define PROBE10 PROBE PROBE PROBE PROBE PROBE \
  61. PROBE PROBE PROBE PROBE PROBE
  62. #define PROBE100 PROBE10 PROBE10 PROBE10 PROBE10 PROBE10 \
  63. PROBE10 PROBE10 PROBE10 PROBE10 PROBE10
  64. #define PROBE1000 PROBE100 PROBE100 PROBE100 PROBE100 PROBE100 \
  65. PROBE100 PROBE100 PROBE100 PROBE100 PROBE100
  66. #define PROBE10000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE1000 \
  67. PROBE1000 PROBE1000 PROBE1000 PROBE1000 PROBE1000
  68. static int usdt(void)
  69. {
  70. PROBE10000
  71. PROBE10000
  72. PROBE10000
  73. PROBE10000
  74. PROBE10000
  75. return 0;
  76. }
  77. extern char build_id_start[];
  78. extern char build_id_end[];
  79. int __attribute__((weak)) trigger_uprobe(bool build_id_resident)
  80. {
  81. int page_sz = sysconf(_SC_PAGESIZE);
  82. void *addr;
  83. /* page-align build ID start */
  84. addr = (void *)((uintptr_t)&build_id_start & ~(page_sz - 1));
  85. /* to guarantee MADV_PAGEOUT work reliably, we need to ensure that
  86. * memory range is mapped into current process, so we unconditionally
  87. * do MADV_POPULATE_READ, and then MADV_PAGEOUT, if necessary
  88. */
  89. madvise(addr, page_sz, MADV_POPULATE_READ);
  90. if (!build_id_resident)
  91. madvise(addr, page_sz, MADV_PAGEOUT);
  92. (void)uprobe();
  93. return 0;
  94. }
  95. int main(int argc, char **argv)
  96. {
  97. if (argc != 2)
  98. goto error;
  99. if (!strcmp("bench", argv[1]))
  100. return bench();
  101. if (!strcmp("usdt", argv[1]))
  102. return usdt();
  103. if (!strcmp("uprobe-paged-out", argv[1]))
  104. return trigger_uprobe(false /* page-out build ID */);
  105. if (!strcmp("uprobe-paged-in", argv[1]))
  106. return trigger_uprobe(true /* page-in build ID */);
  107. error:
  108. fprintf(stderr, "usage: %s <bench|usdt>\n", argv[0]);
  109. return -1;
  110. }