source: src/Helpers/Assert.cpp@ 90aeb9

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 90aeb9 was 90aeb9, checked in by Tillmann Crueger <crueger@…>, 14 years ago

Added a method to access the backtrace when an assert fails

  • 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 bool res,
62 const char* condition,
63 const char* message,
64 const char* filename,
65 const int line,
66 bool& ignore)
67{
68 if(!res){
69 cout << "Assertion \"" << condition << "\" failed in file " << filename << " at line " << line << endl;
70 cout << "Assertion Message: " << message << std::endl;
71 while(true){
72 char choice;
73 if(defaultAction==Assert::Ask) {
74#ifdef __GNUC__
75 cout << "Please choose: (a)bort, (t)hrow execption, show (b)actrace, (i)gnore, al(w)ays ignore" << endl;
76#else
77 cout << "Please choose: (a)bort, (t)hrow execption, (i)gnore, al(w)ays ignore" << endl;
78#endif /* __GNUC__ */
79 cin >> choice;
80 }
81 else{
82 choice = ActionKeys[defaultAction];
83 }
84 switch(choice){
85 case 'a':
86 return true;
87 break;
88 case 't':
89 throw AssertionFailure(condition,filename,line,message);
90 break;
91#ifdef __GNUC__
92 case 'b':
93 Assert::_my_assert::backtrace(filename,line);
94 break;
95#endif /* __GNUC__ */
96 case 'w':
97 ignore = true;
98 // fallthrough
99 case 'i':
100 return false;
101 break;
102 }
103 }
104 }
105 return false;
106}
107
108#ifdef __GNUC__
109void Assert::_my_assert::backtrace(const char *file, int line){
110 const size_t max_depth = 100;
111 void* stack_addrs[max_depth];
112 size_t stack_depth;
113 char **stack_strings=0;
114 const char *func_name=0;
115 size_t sz = 64;
116
117 // get the backtrace
118 stack_depth = ::backtrace(stack_addrs,max_depth);
119 stack_strings = backtrace_symbols(stack_addrs, stack_depth);
120 // used later for demangling
121 // reserved here, so we can free it unconditionally
122 char *dm_function = static_cast<char*>(malloc(sz));
123 if(!dm_function){
124 // malloc failed... we are out of luck
125 cout << "cannot provide stack trace due to exhausted memory" << endl;
126 return;
127 }
128
129 cout << "Backtrace from " << file << "@" << line << ":" << endl;
130
131 // i=2 because we don't want this function, nor the assertion handler
132 for(unsigned int i=2;i<stack_depth-2;++i){
133 // find the mangled function name
134 char *begin = stack_strings[i];
135 // function name starts with a (
136 while(*begin && *begin!='(') ++begin;
137 char *end=begin;
138 while(*end && *end!='+') ++end;
139
140 // see if we found our function name
141 if(*begin && *end){
142 *begin++ = 0;
143 *end = 0;
144 // use the C++ demangler
145
146 int status;
147 char *func_ret = abi::__cxa_demangle(begin, dm_function, &sz, &status);
148 if(func_ret){
149 // abi might have realloced...
150 dm_function = func_ret;
151 func_name = dm_function;
152 }
153 else{
154 // demangling failed... get the function name without demangling
155 func_name = begin;
156 }
157 }
158 else{
159 // function name not found... get the whole line
160 func_name = stack_strings[i];
161 }
162 cout << func_name << endl;
163 }
164 free(dm_function);
165 free(stack_strings); // malloc()ed by backtrace_symbols
166}
167#endif /* __GNUC__ */
168
169void Assert::_my_assert::doHooks(){
170 for(vector<hook_t>::reverse_iterator iter = hooks.rbegin(); iter!=hooks.rend(); ++iter ){
171 (*iter)();
172 }
173}
174
175void Assert::_my_assert::addHook(hook_t hook){
176 hooks.push_back(hook);
177}
178
179void Assert::_my_assert::removeHook(Assert::hook_t hook){
180 for(vector<hook_t>::iterator iter = hooks.begin(); iter!=hooks.end();){
181 if((*iter)==hook){
182 iter = hooks.erase(iter);
183 }
184 else{
185 ++iter;
186 }
187 }
188}
189
190void Assert::_my_assert::setDefault(Assert::Action action){
191 defaultAction = action;
192}
193Assert::Action Assert::_my_assert::getDefault(){
194 return defaultAction;
195}
196std::string Assert::_my_assert::printDefault(){
197 return ActionNames[defaultAction];
198}
199
200#endif
201
Note: See TracBrowser for help on using the repository browser.