LogService
libdadi: utility tools for distributed applications
debug.hh
1 /****************************************************************************/
2 /* Log debug utils header */
3 /* */
4 /* Author(s): */
5 /* - Philippe COMBES (Philippe.Combes@ens-lyon.fr) */
6 /* - Frederic LOMBARD (Frederic.Lombard@lifc.univ-fcomte.fr) */
7 /* */
8 /* This file is part of DIET . */
9 /* */
10 /* Copyright (C) 2000-2003 ENS Lyon, LIFC, INSA, INRIA and SysFera (2000) */
11 /* */
12 /* - Frederic.Desprez@ens-lyon.fr (Project Manager) */
13 /* - Eddy.Caron@ens-lyon.fr (Technical Manager) */
14 /* - Tech@sysfera.com (Maintainer and Technical Support) */
15 /* */
16 /* This software is a computer program whose purpose is to provide an */
17 /* distributed logging services. */
18 /* */
19 /* */
20 /* This software is governed by the CeCILL license under French law and */
21 /* abiding by the rules of distribution of free software. You can use, */
22 /* modify and/ or redistribute the software under the terms of the CeCILL */
23 /* license as circulated by CEA, CNRS and INRIA at the following URL */
24 /* "http://www.cecill.info". */
25 /* */
26 /* As a counterpart to the access to the source code and rights to copy, */
27 /* modify and redistribute granted by the license, users are provided */
28 /* only with a limited warranty and the software's author, the holder */
29 /* of the economic rights, and the successive licensors have only */
30 /* limited liability. */
31 /* */
32 /* In this respect, the user's attention is drawn to the risks */
33 /* associated with loading, using, modifying and/or developing or */
34 /* reproducing the software by the user in light of its specific status */
35 /* of free software, that may mean that it is complicated to */
36 /* manipulate, and that also therefore means that it is reserved for */
37 /* developers and experienced professionals having in-depth computer */
38 /* knowledge. Users are therefore encouraged to load and test the */
39 /* software's suitability as regards their requirements in conditions */
40 /* enabling the security of their systems and/or data to be ensured and, */
41 /* more generally, to use and operate it in the same conditions as */
42 /* regards security. */
43 /* */
44 /* The fact that you are presently reading this means that you have had */
45 /* knowledge of the CeCILL license and that you accept its terms. */
46 /* */
47 /****************************************************************************/
48 
49 #ifndef _DEBUG_HH_
50 #define _DEBUG_HH_
51 
52 #include <cmath> /* include used for the definition of HUGE_VAL*/
53 #include <cstdio>
54 #include <cstdlib>
55 #include <ctime>
56 #include <iostream>
57 #include <sys/time.h>
58 #include <unistd.h>
59 #include <omniconfig.h>
60 #include <omnithread.h>
61 
62 
64 extern unsigned int TRACE_LEVEL;
66 extern omni_mutex debug_log_mutex;
67 
71 #define NO_TRACE 0
72 #define TRACE_ERR_AND_WARN 1
73 #define TRACE_MAIN_STEPS 2
74 #define TRACE_ALL_STEPS 5
75 #define TRACE_STRUCTURES 10
76 #define TRACE_MAX_VALUE TRACE_STRUCTURES
77 #define TRACE_DEFAULT TRACE_MAIN_STEPS
78 
84 #ifndef EXIT_FUNCTION
85 #define EXIT_FUNCTION \
86  std::cout << "DEBUG WARNING: EXIT_FUNCTION undeclared !\n"
87 #endif
88 
89 
93 #ifndef MIN
94 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
95 #endif /* MIN */
96 #ifndef MAX
97 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
98 #endif /* MAX */
99 
104 #define BIP printf("bip - " __FILE__ " %i\n", __LINE__)
105 
109 #define ERROR(formatted_msg, return_value) { \
110  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \
111  debug_log_mutex.lock(); \
112  std::cerr << "LOG ERROR: " << formatted_msg << ".\n"; \
113  debug_log_mutex.unlock(); \
114  } \
115  return return_value; }
116 
117 #define ERROR_EXIT(formatted_msg) { \
118  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \
119  debug_log_mutex.lock(); \
120  std::cerr << "LOG ERROR: " << formatted_msg << ".\n"; \
121  debug_log_mutex.unlock(); \
122  } \
123  exit(1); }
124 
125 #define INTERNAL_ERROR_EXIT(formatted_msg) { \
126  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \
127  debug_log_mutex.lock(); \
128  std::cerr << "LOG ERROR: " << formatted_msg << ".\n"; \
129  debug_log_mutex.unlock(); \
130  } \
131  exit(1); }
132 
136 #define WARNING(formatted_msg) \
137  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \
138  debug_log_mutex.lock(); \
139  std::cerr << "LOG WARNING: " << formatted_msg << ".\n"; \
140  debug_log_mutex.unlock(); }
141 
142 
146 #define INTERNAL_ERROR(formatted_msg, exit_value) \
147  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \
148  debug_log_mutex.lock(); \
149  std::cerr << "LOG INTERNAL ERROR: " << formatted_msg << ".\n" << \
150  "Please send bug report to diet-usr@ens-lyon.fr\n"; \
151  debug_log_mutex.unlock(); } \
152  EXIT_FUNCTION; \
153  exit(exit_value)
154 
158 #define INTERNAL_WARNING(formatted_msg) \
159  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(TRACE_ERR_AND_WARN)) { \
160  debug_log_mutex.lock(); \
161  std::cerr << "LOG INTERNAL WARNING: " << formatted_msg << ".\n" \
162  << "This is not a fatal bug, but please send a report " \
163  "to diet-dev@ens-lyon.fr\n"; \
164  debug_log_mutex.unlock(); }
165 
166 
167 // DEBUG pause: insert a pause of duration <s>+<us>E-6 seconds
168 #define PAUSE(s, us) \
169  { \
170  struct timeval tv; \
171  tv.tv_sec = s; \
172  tv.tv_usec = us; \
173  select(0, NULL, NULL, NULL, &tv); \
174  }
175 
176 
177 // DEBUG trace: print "function(formatted_text)\n", following the iostream
178 // format. First argument is the minimum TRACE_LEVEL for the line to be printed.
179 #define TRACE_FUNCTION(level, formatted_text) \
180  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \
181  debug_log_mutex.lock(); \
182  std::cout << __FUNCTION__ << '(' << formatted_text << ")\n"; \
183  debug_log_mutex.unlock(); }
184 
185 // DEBUG trace: print formatted_text following the iostream format (no '\n'
186 // added). First argument is the minimum TRACE_LEVEL for the line to be printed.
187 #define TRACE_TEXT(level, formatted_text) \
188  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \
189  debug_log_mutex.lock(); \
190  std::cout << formatted_text; \
191  debug_log_mutex.unlock(); }
192 
193 // DEBUG trace: print "file:line: formatted_text", following the iostream format
194 // (no '\n' added). First argument is the minimum TRACE_LEVEL for the line to be
195 // printed.
196 #define TRACE_TEXT_POS(level, formatted_text) \
197  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \
198  debug_log_mutex.lock(); \
199  std::cout << __FILE__ << ':' << __LINE__ << ": " << formatted_text; \
200  debug_log_mutex.unlock(); }
201 
202 // DEBUG trace: print "time: formatted_text", following the iostream format (no
203 // '\n' added). First argument is the minimum TRACE_LEVEL for the line to be
204 // printed.
205 #define TRACE_TIME(level, formatted_text) \
206  if (static_cast<int>(TRACE_LEVEL) >= static_cast<int>(level)) { \
207  struct timeval tv; \
208  debug_log_mutex.lock(); \
209  gettimeofday(&tv, NULL); \
210  printf("%10ld.%06ld: ", \
211  (unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec); \
212  std::cout << formatted_text; \
213  debug_log_mutex.unlock(); \
214  }
215 
216 // DEBUG trace: print variable name and value
217 #define TRACE_VAR(var) { \
218  debug_log_mutex.lock(); \
219  TRACE_TEXT_POS(NO_TRACE, #var << " = " << (var) << "\n"); \
220  debug_log_mutex.unlock(); }
221 
222 
223 
224 #endif // _DEBUG_HH_