dwarf-unwind.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <linux/compiler.h>
  2. #include <linux/types.h>
  3. #include <unistd.h>
  4. #include "tests.h"
  5. #include "debug.h"
  6. #include "machine.h"
  7. #include "event.h"
  8. #include "unwind.h"
  9. #include "perf_regs.h"
  10. #include "map.h"
  11. #include "thread.h"
  12. static int mmap_handler(struct perf_tool *tool __maybe_unused,
  13. union perf_event *event,
  14. struct perf_sample *sample __maybe_unused,
  15. struct machine *machine)
  16. {
  17. return machine__process_mmap2_event(machine, event, NULL);
  18. }
  19. static int init_live_machine(struct machine *machine)
  20. {
  21. union perf_event event;
  22. pid_t pid = getpid();
  23. return perf_event__synthesize_mmap_events(NULL, &event, pid, pid,
  24. mmap_handler, machine, true);
  25. }
  26. #define MAX_STACK 6
  27. static int unwind_entry(struct unwind_entry *entry, void *arg)
  28. {
  29. unsigned long *cnt = (unsigned long *) arg;
  30. char *symbol = entry->sym ? entry->sym->name : NULL;
  31. static const char *funcs[MAX_STACK] = {
  32. "test__arch_unwind_sample",
  33. "unwind_thread",
  34. "krava_3",
  35. "krava_2",
  36. "krava_1",
  37. "test__dwarf_unwind"
  38. };
  39. if (*cnt >= MAX_STACK) {
  40. pr_debug("failed: crossed the max stack value %d\n", MAX_STACK);
  41. return -1;
  42. }
  43. if (!symbol) {
  44. pr_debug("failed: got unresolved address 0x%" PRIx64 "\n",
  45. entry->ip);
  46. return -1;
  47. }
  48. pr_debug("got: %s 0x%" PRIx64 "\n", symbol, entry->ip);
  49. return strcmp((const char *) symbol, funcs[(*cnt)++]);
  50. }
  51. __attribute__ ((noinline))
  52. static int unwind_thread(struct thread *thread, struct machine *machine)
  53. {
  54. struct perf_sample sample;
  55. unsigned long cnt = 0;
  56. int err = -1;
  57. memset(&sample, 0, sizeof(sample));
  58. if (test__arch_unwind_sample(&sample, thread)) {
  59. pr_debug("failed to get unwind sample\n");
  60. goto out;
  61. }
  62. err = unwind__get_entries(unwind_entry, &cnt, machine, thread,
  63. &sample, MAX_STACK);
  64. if (err)
  65. pr_debug("unwind failed\n");
  66. else if (cnt != MAX_STACK) {
  67. pr_debug("got wrong number of stack entries %lu != %d\n",
  68. cnt, MAX_STACK);
  69. err = -1;
  70. }
  71. out:
  72. free(sample.user_stack.data);
  73. free(sample.user_regs.regs);
  74. return err;
  75. }
  76. __attribute__ ((noinline))
  77. static int krava_3(struct thread *thread, struct machine *machine)
  78. {
  79. return unwind_thread(thread, machine);
  80. }
  81. __attribute__ ((noinline))
  82. static int krava_2(struct thread *thread, struct machine *machine)
  83. {
  84. return krava_3(thread, machine);
  85. }
  86. __attribute__ ((noinline))
  87. static int krava_1(struct thread *thread, struct machine *machine)
  88. {
  89. return krava_2(thread, machine);
  90. }
  91. int test__dwarf_unwind(void)
  92. {
  93. struct machines machines;
  94. struct machine *machine;
  95. struct thread *thread;
  96. int err = -1;
  97. machines__init(&machines);
  98. machine = machines__find(&machines, HOST_KERNEL_ID);
  99. if (!machine) {
  100. pr_err("Could not get machine\n");
  101. return -1;
  102. }
  103. if (init_live_machine(machine)) {
  104. pr_err("Could not init machine\n");
  105. goto out;
  106. }
  107. if (verbose > 1)
  108. machine__fprintf(machine, stderr);
  109. thread = machine__find_thread(machine, getpid(), getpid());
  110. if (!thread) {
  111. pr_err("Could not get thread\n");
  112. goto out;
  113. }
  114. err = krava_1(thread, machine);
  115. out:
  116. machine__delete_threads(machine);
  117. machine__exit(machine);
  118. machines__exit(&machines);
  119. return err;
  120. }