Line data Source code
1 : /*
2 : * DUNE DAQ modification notice:
3 : * This file has been modified from the original ATLAS ers source for the DUNE DAQ project.
4 : * Fork baseline commit: 8267df82a4f6fe6bf02c4014923eba19eddc4614 (2020-04-14).
5 : * Renamed since fork: yes (from src/Context.cxx to src/Context.cpp).
6 : *
7 : * Original copyright:
8 : * Copyright (C) 2001-2020 CERN for the benefit of the ATLAS collaboration.
9 : * Licensed under the Apache License, Version 2.0.
10 : */
11 :
12 : /*
13 : * Context.cxx
14 : * ers
15 : *
16 : * Created by Serguei Kolos on 26.11.05.
17 : * Copyright 2004 CERN. All rights reserved.
18 : *
19 : */
20 : #include <cxxabi.h>
21 : #include <pwd.h>
22 : #include <string.h>
23 : #include <sys/types.h>
24 : #include <unistd.h>
25 :
26 : #include <iostream>
27 : #include <sstream>
28 :
29 : #ifndef __rtems__
30 : #include <execinfo.h>
31 : #else
32 : char**
33 : backtrace_symbols(void**, int size)
34 : {
35 : return 0;
36 : }
37 : #endif
38 :
39 : #include <ers/Configuration.hpp>
40 : #include <ers/Context.hpp>
41 :
42 : namespace {
43 : std::string
44 0 : demangle(char* mangled)
45 : {
46 0 : int status;
47 0 : char* function_begin = ::strchr(mangled, '(');
48 0 : if (function_begin) {
49 0 : char* function_end = ::strchr(++function_begin, '+');
50 0 : if (function_end && function_end != function_begin) {
51 0 : std::string fname(function_begin, function_end - function_begin);
52 0 : char* name = abi::__cxa_demangle(fname.c_str(), 0, 0, &status);
53 :
54 0 : if (!name) {
55 0 : return std::string(mangled);
56 : }
57 :
58 0 : std::ostringstream out;
59 0 : out << std::string(mangled, function_begin - mangled) << name << function_end;
60 0 : free(name);
61 0 : return out.str();
62 0 : }
63 : }
64 0 : return std::string(mangled);
65 : }
66 :
67 : void
68 1086 : print_function(std::ostream& out, const char* function, int verbosity)
69 : {
70 1086 : if (verbosity) {
71 0 : out << function;
72 0 : return;
73 : }
74 :
75 1086 : const char* end = strchr(function, '(');
76 1086 : if (end) {
77 : const char* beg = end;
78 60353 : while (beg > function) {
79 60041 : if (*(beg - 1) == ' ') {
80 : break;
81 : }
82 59267 : --beg;
83 : }
84 1086 : out.write(beg, end - beg);
85 1086 : out << "(...)";
86 : } else {
87 0 : out << function;
88 : }
89 : }
90 : }
91 :
92 : std::vector<std::string>
93 0 : ers::Context::stack() const
94 : {
95 0 : std::vector<std::string> stack;
96 0 : stack.reserve(stack_size());
97 0 : char** symbols = backtrace_symbols((void**)stack_symbols(), stack_size());
98 :
99 0 : if (symbols) {
100 0 : for (int i = 1; i < stack_size(); i++) {
101 0 : stack.push_back(demangle(symbols[i]));
102 : }
103 0 : free(symbols);
104 : }
105 :
106 0 : return stack;
107 0 : }
108 :
109 : /** Pretty printed code position
110 : * format: package_name/file_name:line_number <function_name>
111 : * \return reference to string containing format
112 : */
113 : std::string
114 1086 : ers::Context::position(int verbosity) const
115 : {
116 1086 : std::ostringstream out;
117 1086 : print_function(out, function_name(), verbosity);
118 1086 : out << " at ";
119 :
120 1086 : const char* file = file_name();
121 1086 : if (file[0] == '.' && file[1] == '.' && file[2] == '/') // file name starts with "../"
122 : {
123 0 : out << package_name() << (file + 2);
124 : } else {
125 1086 : out << file;
126 : }
127 1086 : out << ":" << line_number();
128 2172 : return out.str();
129 1086 : }
|