source: src/Helpers/Assert.cpp@ 0e2031

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 0e2031 was 23359f, checked in by Frederik Heber <heber@…>, 14 years ago

Assert's internal check now uses std::string instead of const char *.

  • This allows for stuff like: "i = "+std::string(i)+" is too big"
  • no changes are necessary elsewhere
  • 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 "Helpers/MemDebug.hpp"
21
22#include "Helpers/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 = Ask;
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.