source: rrlib_rtti/rtti.cpp @ 76:bfb88a01fcd4

Last change on this file since 76:bfb88a01fcd4 was 76:bfb88a01fcd4, checked in by Max Reichardt <mreichardt@…>, 4 years ago

Added #define to disable auto-detection of binaries performing static initialization of data types, as this does not work on platforms with erroneous stack traces (is an optional feature anyway). Added more test cases ensuring that auto-detection works correctly - explicitly mentioning that define on failure.

File size: 3.7 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/rtti/rtti.cpp
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2012-02-05
27 *
28 */
29//----------------------------------------------------------------------
30#include "rrlib/rtti/rtti.h"
31
32//----------------------------------------------------------------------
33// External includes (system with <>, local with "")
34//----------------------------------------------------------------------
35#if __linux__
36#include <execinfo.h>
37#endif
38
39//----------------------------------------------------------------------
40// Internal includes with ""
41//----------------------------------------------------------------------
42
43//----------------------------------------------------------------------
44// Debugging
45//----------------------------------------------------------------------
46#include <cassert>
47
48//----------------------------------------------------------------------
49// Namespace usage
50//----------------------------------------------------------------------
51
52//----------------------------------------------------------------------
53// Namespace declaration
54//----------------------------------------------------------------------
55namespace rrlib
56{
57namespace rtti
58{
59
60//----------------------------------------------------------------------
61// Forward declarations / typedefs / enums
62//----------------------------------------------------------------------
63
64//----------------------------------------------------------------------
65// Const values
66//----------------------------------------------------------------------
67
68//----------------------------------------------------------------------
69// Implementation
70//----------------------------------------------------------------------
71
72static std::string GetSoFile(const std::string& backtrace_entry)
73{
74  return backtrace_entry.substr(0, backtrace_entry.find('('));
75}
76
77std::string GetBinaryCurrentlyPerformingStaticInitialization()
78{
79#if RRLIB_RTTI_BINARY_DETECTION_ENABLED
80  // system .so file that does dynamic loading
81  static std::string ld_so_file;
82
83  // implementation uses backtrace to find this out
84  void* array[255];
85  int len = backtrace(array, 255);
86  if (len == 0)
87  {
88    RRLIB_LOG_PRINT_STATIC(ERROR, "Empty stack trace.");
89    return "";
90  }
91  char** symbols = backtrace_symbols(array, len);
92  if (ld_so_file.length() == 0)
93  {
94    ld_so_file = GetSoFile(symbols[len - 1]);
95    RRLIB_LOG_PRINT_STATIC(DEBUG_VERBOSE_1, "System library for loading .so files: ", ld_so_file);
96  }
97
98  for (int i = 1; i < len; i++)
99  {
100    std::string so = GetSoFile(symbols[i]);
101    if (so.compare(ld_so_file) == 0)
102    {
103      std::string result = GetSoFile(symbols[i - 1]);
104      free(symbols);
105      return result;
106    }
107  }
108
109  free(symbols);
110#endif
111  return "";
112}
113
114//----------------------------------------------------------------------
115// End of namespace declaration
116//----------------------------------------------------------------------
117}
118}
Note: See TracBrowser for help on using the repository browser.