blob: 598c9da09910bb5c0b7034b4e75fe454e1fc39c5 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "wpi/StackTrace.h"
6
7#include <execinfo.h>
8
9#include "wpi/Demangle.h"
10#include "wpi/SmallString.h"
Austin Schuh812d0d12021-11-04 20:16:48 -070011#include "wpi/StringExtras.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080012#include "wpi/raw_ostream.h"
13
14namespace wpi {
15
16std::string GetStackTrace(int offset) {
17 void* stackTrace[128];
18 int stackSize = backtrace(stackTrace, 128);
19 char** mangledSymbols = backtrace_symbols(stackTrace, stackSize);
20 wpi::SmallString<1024> buf;
21 wpi::raw_svector_ostream trace(buf);
22
23 for (int i = offset; i < stackSize; i++) {
24 // Only print recursive functions once in a row.
25 if (i == 0 || stackTrace[i] != stackTrace[i - 1]) {
Austin Schuh1e69f942020-11-14 15:06:14 -080026 // extract just function name from "pathToExe(functionName+offset)"
Austin Schuh812d0d12021-11-04 20:16:48 -070027 std::string_view sym = split(mangledSymbols[i], '(').second;
28 std::string_view offset;
29 std::tie(sym, offset) = split(sym, '+');
30 std::string_view addr;
31 std::tie(offset, addr) = split(offset, ')');
32 trace << "\tat " << Demangle(sym) << " + " << offset << addr << "\n";
Brian Silverman8fce7482020-01-05 13:18:21 -080033 }
34 }
35
36 std::free(mangledSymbols);
37
Austin Schuh812d0d12021-11-04 20:16:48 -070038 return std::string{trace.str()};
Brian Silverman8fce7482020-01-05 13:18:21 -080039}
40
41} // namespace wpi