source: ThirdParty/CodePatterns/src/Helpers/Assert.cpp@ 7516f6

Action_Thermostats Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Exclude_Hydrogens_annealWithBondGraph Fix_Verbose_Codepatterns ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision
Last change on this file since 7516f6 was 9eb71b3, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

Commented out MemDebug include and Memory::ignore.

  • MemDebug clashes with various allocation operators that use a specific placement in memory. It is so far not possible to wrap new/delete fully. Hence, we stop this effort which so far has forced us to put ever more includes (with clashes) into MemDebug and thereby bloat compilation time.
  • MemDebug does not add that much usefulness which is not also provided by valgrind.
  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * Assert.cpp
10 *
11 * Created on: Mar 18, 2010
12 * Author: crueger
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20//#include "CodePatterns/MemDebug.hpp"
21
22#include "CodePatterns/Assert.hpp"
23#include <iostream>
24
25using namespace std;
26
27namespace Assert{
28 AssertionFailure::AssertionFailure(std::string _condition,
29 std::string _file,
30 int _line,
31 std::string _message) :
32 condition(_condition),
33 file(_file),
34 line(_line),
35 message(_message)
36 {}
37
38 std::string AssertionFailure::getFile(){
39 return file;
40 }
41
42 int AssertionFailure::getLine(){
43 return line;
44 }
45
46 std::string AssertionFailure::getMessage(){
47 return message;
48 }
49
50 std::ostream& AssertionFailure::operator<<(std::ostream& out){
51 out << "Assertion \"" << condition << "\" failed in file " << file << " at line " << line << endl;
52 out << "Assertion Message: " << message << std::endl;
53 return out;
54 }
55
56 const char ActionKeys[] = {'\0','a','t','i'};
57 const char* ActionNames[] = {"Ask","Abort","Throw","Ignore"};
58}
59
60#ifndef NDEBUG
61
62#ifdef __GNUC__
63#include <cstdlib>
64#include <execinfo.h>
65#include <cxxabi.h>
66#endif
67
68Assert::Action Assert::_my_assert::defaultAction = Abort;
69std::vector<Assert::hook_t> Assert::_my_assert::hooks;
70
71std::map<std::string,bool> Assert::_wrapper::ignores;
72const char* Assert::_wrapper::message_ptr = "source pointer did not point to object of desired type";
73const char* Assert::_wrapper::message_ref = "source reference did not contain object of desired type";
74
75bool Assert::_my_assert::check(const char* condition,
76 std::string message,
77 const char* filename,
78 const int line,
79 bool& ignore)
80{
81 cout << "Assertion \"" << condition << "\" failed in file " << filename << " at line " << line << endl;
82 cout << "Assertion Message: " << message << std::endl;
83 while(true){
84 char choice;
85 if(defaultAction==Assert::Ask) {
86#ifdef __GNUC__
87 cout << "Please choose: (a)bort, (t)hrow execption, show (b)actrace, (i)gnore, al(w)ays ignore" << endl;
88#else
89 cout << "Please choose: (a)bort, (t)hrow execption, (i)gnore, al(w)ays ignore" << endl;
90#endif /* __GNUC__ */
91 cin >> choice;
92 }
93 else{
94 choice = ActionKeys[defaultAction];
95 }
96 switch(choice){
97 case 'a':
98 return true;
99 break;
100 case 't':
101 throw AssertionFailure(condition,filename,line,message);
102 break;
103#ifdef __GNUC__
104 case 'b':
105 Assert::_my_assert::backtrace(filename,line);
106 break;
107#endif /* __GNUC__ */
108 case 'w':
109 ignore = true;
110 // fallthrough
111 case 'i':
112 return false;
113 break;
114 }
115 }
116 return false;
117}
118
119#ifdef __GNUC__
120void Assert::_my_assert::backtrace(const char *file, int line){
121 const size_t max_depth = 100;
122 void* stack_addrs[max_depth];
123 size_t stack_depth;
124 char **stack_strings=0;
125 const char *func_name=0;
126 size_t sz = 64;
127
128 // get the backtrace
129 stack_depth = ::backtrace(stack_addrs,max_depth);
130 stack_strings = backtrace_symbols(stack_addrs, stack_depth);
131 // used later for demangling
132 // reserved here, so we can free it unconditionally
133 char *dm_function = static_cast<char*>(malloc(sz));
134 if(!dm_function){
135 // malloc failed... we are out of luck
136 cout << "cannot provide stack trace due to exhausted memory" << endl;
137 return;
138 }
139
140 cout << "Backtrace from " << file << "@" << line << ":" << endl;
141
142 // i=2 because we don't want this function, nor the assertion handler
143 for(unsigned int i=2;i<stack_depth-2;++i){
144 // find the mangled function name
145 char *begin = stack_strings[i];
146 // function name starts with a (
147 while(*begin && *begin!='(') ++begin;
148 char *end=begin;
149 while(*end && *end!='+') ++end;
150
151 // see if we found our function name
152 if(*begin && *end){
153 *begin++ = 0;
154 *end = 0;
155 // use the C++ demangler
156
157 int status;
158 char *func_ret = abi::__cxa_demangle(begin, dm_function, &sz, &status);
159 if(func_ret){
160 // abi might have realloced...
161 dm_function = func_ret;
162 func_name = dm_function;
163 }
164 else{
165 // demangling failed... get the function name without demangling
166 func_name = begin;
167 }
168 }
169 else{
170 // function name not found... get the whole line
171 func_name = stack_strings[i];
172 }
173 cout << func_name << endl;
174 }
175 free(dm_function);
176 free(stack_strings); // malloc()ed by backtrace_symbols
177}
178#endif /* __GNUC__ */
179
180void Assert::_my_assert::doHooks(){
181 for(vector<hook_t>::reverse_iterator iter = hooks.rbegin(); iter!=hooks.rend(); ++iter ){
182 (*iter)();
183 }
184}
185
186void Assert::_my_assert::addHook(hook_t hook){
187 hooks.push_back(hook);
188}
189
190void Assert::_my_assert::removeHook(Assert::hook_t hook){
191 for(vector<hook_t>::iterator iter = hooks.begin(); iter!=hooks.end();){
192 if((*iter)==hook){
193 iter = hooks.erase(iter);
194 }
195 else{
196 ++iter;
197 }
198 }
199}
200
201void Assert::_my_assert::setDefault(Assert::Action action){
202 defaultAction = action;
203}
204Assert::Action Assert::_my_assert::getDefault(){
205 return defaultAction;
206}
207std::string Assert::_my_assert::printDefault(){
208 return ActionNames[defaultAction];
209}
210
211#endif
212
Note: See TracBrowser for help on using the repository browser.