brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 838df6b Raw
169 lines · cpp
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10// TODO: Investigate this failure on x86_64 macOS back deployment11// XFAIL: stdlib=system && target=x86_64-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}12 13// TODO: Figure out why this fails with Memory Sanitizer.14// XFAIL: msan15 16#include <libunwind.h>17#include <stdlib.h>18#include <stdio.h>19#include <string.h>20 21void backtrace(int lower_bound) {22  unw_context_t context;23  unw_getcontext(&context);24 25  unw_cursor_t cursor;26  unw_init_local(&cursor, &context);27 28  char buffer[1024];29  unw_word_t offset = 0;30 31  int n = 0;32  do {33    n++;34    if (unw_get_proc_name(&cursor, buffer, sizeof(buffer), &offset) == 0) {35      fprintf(stderr, "Frame %d: %s+%p\n", n, buffer, (void*)offset);36    } else {37      fprintf(stderr, "Frame %d: Could not get name for cursor\n", n);38    }39    if (n > 100) {40      abort();41    }42  } while (unw_step(&cursor) > 0);43 44  if (n < lower_bound) {45    abort();46  }47}48 49__attribute__((noinline)) void test1(int i) {50  fprintf(stderr, "starting %s\n", __func__);51  backtrace(i);52  fprintf(stderr, "finished %s\n", __func__); // ensure return address is saved53}54 55__attribute__((noinline)) void test2(int i, int j) {56  fprintf(stderr, "starting %s\n", __func__);57  backtrace(i);58  test1(j);59  fprintf(stderr, "finished %s\n", __func__); // ensure return address is saved60}61 62__attribute__((noinline)) void test3(int i, int j, int k) {63  fprintf(stderr, "starting %s\n", __func__);64  backtrace(i);65  test2(j, k);66  fprintf(stderr, "finished %s\n", __func__); // ensure return address is saved67}68 69void test_no_info() {70  unw_context_t context;71  unw_getcontext(&context);72 73  unw_cursor_t cursor;74  unw_init_local(&cursor, &context);75 76  unw_proc_info_t info;77  int ret = unw_get_proc_info(&cursor, &info);78  if (ret != UNW_ESUCCESS)79    abort();80 81  // Set the IP to an address clearly outside any function.82  unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)0);83 84  ret = unw_get_proc_info(&cursor, &info);85  if (ret != UNW_ENOINFO)86    abort();87}88 89void test_reg_names() {90  unw_context_t context;91  unw_getcontext(&context);92 93  unw_cursor_t cursor;94  unw_init_local(&cursor, &context);95 96  int max_reg_num = -100;97#if defined(__i386__)98  max_reg_num = 7;99#elif defined(__x86_64__)100  max_reg_num = 32;101#endif102 103  const char prefix[] = "unknown";104  for (int i = -2; i < max_reg_num; ++i) {105    if (strncmp(prefix, unw_regname(&cursor, i), sizeof(prefix) - 1) == 0)106      abort();107  }108 109  if (strncmp(prefix, unw_regname(&cursor, max_reg_num + 1),110              sizeof(prefix) - 1) != 0)111    abort();112}113 114#if defined(__x86_64__)115void test_reg_get_set() {116  unw_context_t context;117  unw_getcontext(&context);118 119  unw_cursor_t cursor;120  unw_init_local(&cursor, &context);121 122  for (int i = 0; i < 17; ++i) {123    const unw_word_t set_value = 7;124    if (unw_set_reg(&cursor, i, set_value) != UNW_ESUCCESS)125      abort();126 127    unw_word_t get_value = 0;128    if (unw_get_reg(&cursor, i, &get_value) != UNW_ESUCCESS)129      abort();130 131    if (set_value != get_value)132      abort();133  }134}135 136void test_fpreg_get_set() {137  unw_context_t context;138  unw_getcontext(&context);139 140  unw_cursor_t cursor;141  unw_init_local(&cursor, &context);142 143  // get/set is not implemented for x86_64 fpregs.144  for (int i = 17; i < 33; ++i) {145    const unw_fpreg_t set_value = 7;146    if (unw_set_fpreg(&cursor, i, set_value) != UNW_EBADREG)147      abort();148 149    unw_fpreg_t get_value = 0;150    if (unw_get_fpreg(&cursor, i, &get_value) != UNW_EBADREG)151      abort();152  }153}154#else155void test_reg_get_set() {}156void test_fpreg_get_set() {}157#endif158 159int main(int, char**) {160  test1(3);161  test2(3, 4);162  test3(3, 4, 5);163  test_no_info();164  test_reg_names();165  test_reg_get_set();166  test_fpreg_get_set();167  return 0;168}169