source: src/Helpers/Assert.cpp@ 506d2f

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 506d2f was 506d2f, checked in by Tillmann Crueger <crueger@…>, 14 years ago

Speed up of ASSERT macro by only calling the _my_assert::check() function when an assertion needs to be handled

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