Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2012-2019 The plumed team
3 : (see the PEOPLE file at the root of the distribution for a list of names)
4 :
5 : See http://www.plumed.org for more information.
6 :
7 : This file is part of plumed, version 2.
8 :
9 : plumed is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : plumed is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 : #include "Exception.h"
23 :
24 : #if defined(__PLUMED_HAS_EXECINFO)
25 : #include <execinfo.h>
26 : #endif
27 :
28 : #include <cstdio>
29 : #include <cstdlib>
30 :
31 : using namespace std;
32 : namespace PLMD {
33 :
34 96 : std::string Exception::trace() {
35 96 : std::string message="\n\n********** STACK DUMP **********\n";
36 : #ifdef __PLUMED_HAS_EXECINFO
37 : void* callstack[128];
38 96 : int frames = backtrace(callstack, 128);
39 96 : char** strs = backtrace_symbols(callstack, frames);
40 2964 : for (int i = 0; i < frames; ++i) {message+=strs[i]; message+="\n";}
41 96 : free(strs);
42 : #else
43 : message+="not available\n";
44 : #endif
45 : message+="********** END STACK DUMP **********\n";
46 96 : return message;
47 : }
48 :
49 48 : std::string Exception::format(const std::string&msg,const std::string&file,unsigned line,const std::string&function) {
50 : std::string message;
51 96 : if(getenv("PLUMED_STACK_TRACE"))message+=trace();
52 : message+="\n+++ Internal PLUMED error";
53 48 : if(file.length()>0) {
54 : char cline[1000];
55 : sprintf(cline,"%u",line);
56 192 : message += "\n+++ file "+file+", line "+cline;
57 48 : if(function.length()>0) message +=", function "+function;
58 : }
59 96 : if(msg.length()>0) message +="\n+++ message: "+msg;
60 48 : return message;
61 : }
62 :
63 :
64 0 : Exception::Exception():
65 : stackString(trace()),
66 0 : msg(format("","",0,""))
67 : {
68 0 : abortIfExceptionsAreDisabled();
69 0 : }
70 :
71 0 : Exception::Exception(const std::string&msg):
72 : stackString(trace()),
73 0 : msg(format(msg,"",0,""))
74 : {
75 0 : abortIfExceptionsAreDisabled();
76 0 : }
77 :
78 48 : Exception::Exception(const std::string&msg,const std::string&file,unsigned line,const std::string&function):
79 : stackString(trace()),
80 96 : msg(format(msg,file,line,function))
81 : {
82 48 : abortIfExceptionsAreDisabled();
83 48 : }
84 :
85 48 : void Exception::abortIfExceptionsAreDisabled() {
86 : #if ! defined(__PLUMED_HAS_EXCEPTIONS)
87 : fprintf(stderr,"%s","Exceptions are disabled, aborting now\n");
88 : fprintf(stderr,"%s",Exception::what());
89 : fprintf(stderr,"\n");
90 : std::abort();
91 : #endif
92 48 : }
93 :
94 : }
95 :
96 :
|