SIONlib  1.7.7
Scalable I/O library for parallel access to task-local files
sion_debug.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** SIONLIB http://www.fz-juelich.de/jsc/sionlib **
3 *****************************************************************************
4 ** Copyright (c) 2008-2019 **
5 ** Forschungszentrum Juelich, Juelich Supercomputing Centre **
6 ** **
7 ** See the file COPYRIGHT in the package base directory for details **
8 ****************************************************************************/
9 
40 #define _XOPEN_SOURCE 700
41 
42 #include <stdlib.h>
43 #include <stdarg.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include "sion_lock.h"
47 
48 #include "sion_debug.h"
49 #include "sion_internal.h"
50 
51 #define SIONDEBFUNCNAMELEN 50
52 #define MAXOMPTHREADS 300
53 
54 
55 int _sion_get_thread_num_default(void);
56 static int (*_sion_my_get_thread_num)(void) = _sion_get_thread_num_default;
57 
59 static int _sion_debug_first[MAXOMPTHREADS] = {1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
60  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
61  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
62  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
63  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
64 
65  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
66  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
67  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
68  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
69  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
70 
71  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
72  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
73  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
74  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
75  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1};
76 
78 static FILE *_sion_debug_out[MAXOMPTHREADS] = {NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
79  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
80  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
81  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
82  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
83  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
84  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
85  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
86  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
87  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
88 
89  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
90  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
91  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
92  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
93  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
94  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
95  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
96  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
97  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
98  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
99 
100  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
101  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
102  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
103  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
104  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
105  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
106  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
107  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
108  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
109  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL};
110 
112 static int _sion_debug_isdebug[MAXOMPTHREADS] = {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
113  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
114  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
115  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
116  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
117 
118  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
119  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
120  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
121  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
122  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
123 
124  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
125  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
126  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
127  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
128  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
129 
131 static int _sion_debug_myrank[MAXOMPTHREADS] = {-1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
132  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
133  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
134  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
135  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
136 
137  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
138  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
139  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
140  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
141  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
142 
143  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
144  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
145  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
146  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
147  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1};
148 
149 static int _sion_debug_debmask = 1023;
150 static int _sion_debug_debrank1 = -1;
151 static int _sion_debug_debrank2 = -1;
152 static int _sion_debug_silent = 0;
153 static int _sion_debug_isinit = 0;
154 static char * _sion_debug_fn = NULL;
156 #define _DEBUG_INIT_THREAD \
157  int threadid=0; \
158  threadid = _sion_my_get_thread_num(); \
159  if(threadid>MAXOMPTHREADS) threadid=(MAXOMPTHREADS-1);
160 
161 
162 /* default thread number */
163 int _sion_get_thread_num_default(void) {
164  return(0);
165 }
166 
167 /* default thread number */
168 int _sion_debug_set_query_thread_num_function( int (*get_thread_num)(void) ) {
169  _sion_lock();
170  _sion_my_get_thread_num=get_thread_num;
171  _sion_unlock();
172  return(1);
173 }
174 
179 int sion_dprintf(int mask, const char *format, ...)
180 {
181  va_list ap;
182  _DEBUG_INIT_THREAD
183 
184  if (_sion_debug_first[threadid])
186 
187  if ((!_sion_debug_isdebug[threadid]) || !(mask & _sion_debug_debmask))
188  return 1;
189 
190  fprintf(_sion_debug_out[threadid], " ");
191 
192  va_start(ap, format);
193 
194  vfprintf(_sion_debug_out[threadid], format, ap);
195 
196  va_end(ap);
197 
198  return 1;
199 }
200 
205 int sion_dprintfp(int mask, const char *callfunction, int rank, const char *format, ...)
206 {
207  va_list ap;
208  char tmpfuncname[SIONDEBFUNCNAMELEN + 1];
209  char spec[20];
210  int setrank = 0, norank = 0;
211  _DEBUG_INIT_THREAD
212 
213  if ((_sion_debug_myrank[threadid] < 0) && (rank < 0)) {
214  return (0);
215  }
216 
217  /* no rank specified, used previous stored rank */
218  if (rank < 0) {
219  rank = _sion_debug_myrank[threadid];
220  norank = 1;
221  }
222 
223  /* if internal rank is not initialized used rank parameter, otherwise don't overwrite it */
224  if (_sion_debug_myrank[threadid] < 0) {
225  _sion_debug_myrank[threadid] = rank;
226  setrank = 1;
227  }
228  /* if(setrank) */
229  /* fprintf(stderr,"WF: in sion_dprintfp: mask=%d %s rank=%d myrank=%d setrank=%d norank=%d first=%d\n",mask,callfunction,rank,myrank,setrank,norank,_sion_debug_first); */
230 
231  if (_sion_debug_first[threadid])
233 
234  /* fprintf(stderr,"WF: in sion_dprintfp: mask=%d %s rank=%d debmask=%d and=%d\n",mask,callfunction,rank,debmask,mask & debmask); */
235 
236  if ((!_sion_debug_isdebug[threadid]) || !(mask & _sion_debug_debmask))
237  return 1;
238  if ((_sion_debug_debrank1 >= 0) && (_sion_debug_debrank2 >= 0)) {
239  if ((rank != _sion_debug_debrank1) && (rank != _sion_debug_debrank2))
240  return 1;
241  }
242  else if (_sion_debug_debrank1 >= 0) {
243  if (rank != _sion_debug_debrank1)
244  return 1;
245  }
246 
247  if (strlen(callfunction) > SIONDEBFUNCNAMELEN) {
248  strncpy(tmpfuncname, callfunction, SIONDEBFUNCNAMELEN);
249  tmpfuncname[SIONDEBFUNCNAMELEN] = '\0';
250  }
251  else
252  strcpy(tmpfuncname, callfunction);
253 
254  sprintf(spec, "SION[%s%s%%5d][%%-%ds] ", (setrank ? "S" : " "), (norank ? "N" : " "), SIONDEBFUNCNAMELEN);
255  fprintf(_sion_debug_out[threadid], spec, rank, tmpfuncname);
256  if (mask >= 8)
257  fprintf(_sion_debug_out[threadid], " ");
258  if (mask > 64)
259  fprintf(_sion_debug_out[threadid], " ");
260  if (mask >= 128)
261  fprintf(_sion_debug_out[threadid], " ");
262 
263  va_start(ap, format);
264 
265  vfprintf(_sion_debug_out[threadid], format, ap);
266 
267  va_end(ap);
268 
269  fflush(_sion_debug_out[threadid]);
270 
271  return 1;
272 }
273 
277 FILE *sion_get_dfile(void)
278 {
279  _DEBUG_INIT_THREAD
280  if (_sion_debug_first[threadid])
282 
283  return _sion_debug_out[threadid];
284 }
285 
289 void sion_dclose(void)
290 {
291  _DEBUG_INIT_THREAD
292  if (_sion_debug_out[threadid] && (_sion_debug_out[threadid] != stdout) && (_sion_debug_out[threadid] != stderr)) {
293  fclose(_sion_debug_out[threadid]);
294  _sion_debug_out[threadid] = NULL;
295  _sion_debug_first[threadid] = 1;
296  }
297 }
298 
299 int sion_isdebug(void)
300 {
301  _DEBUG_INIT_THREAD
302  if (_sion_debug_first[threadid])
304 
305  return _sion_debug_isdebug[threadid] ? _sion_debug_debmask : 0;
306 }
307 
308 
315 void sion_debug_on(int mask, const char *filename)
316 {
317  char *fname = 0;
318  _DEBUG_INIT_THREAD
319 
320  if (_sion_debug_out[threadid])
321  sion_dclose(); /* close previously opened logfile */
322 
323  _sion_debug_first[threadid] = 0; /* do not call _sion_debug_init() */
324 
325  if (filename) {
326  fname = (char *) malloc((strlen(filename) + 1) * sizeof(char));
327  strcpy(fname, filename);
328  }
329 
330  /* open debug output file (default is stderr) */
331  if (!fname || (strlen(fname) == 0) || !strcmp(fname, "stderr")) {
332  _sion_debug_out[threadid] = stderr;
333  }
334  else if (!strcmp(fname, "stdout")) {
335  _sion_debug_out[threadid] = stdout;
336  }
337  else if (!(_sion_debug_out[threadid] = fopen(fname, "w"))) {
338  fprintf(stderr, "sion_dprintf: failed to open '%s' for writing\n", fname);
339  _sion_debug_out[threadid] = stderr;
340  }
341 
342 #ifdef SION_DEBUG_EXTREME
343  fprintf(stderr, "Warning: you are using a version of SION that is configured with -DEBUG (current debug-mask is %d\n", debmask);
344 #endif
345 
346  if ((_sion_debug_out[threadid] != stdout) && (_sion_debug_out[threadid] != stderr))
347  fprintf(stderr, "Writing debug output to %s\n", fname);
348 
349  if (fname)
350  free(fname);
351 
352  _sion_debug_debmask = mask;
353  _sion_debug_isdebug[threadid] = 1;
354 }
355 
356 void sion_debug_off(void)
357 {
358  _DEBUG_INIT_THREAD
359  _sion_debug_isdebug[threadid] = 0;
360  sion_dclose();
361 }
362 
363 
372 {
373  int rvalue = 1;
374  _DEBUG_INIT_THREAD
375  {
376  if (_sion_debug_first[threadid]) {
377  char *filename = 0;
378 
379  _sion_debug_first[threadid] = 0;
380  _sion_debug_isdebug[threadid] = 0;
381 
382  /* get info from environment only once */
383  _sion_lock();
384  if(_sion_debug_isinit) {
385  _sion_unlock();
386  } else {
387  const char *t;
388 
389  t = _sion_getenv("SION_DEBUG_RANK");
390  if (t)
391  _sion_debug_debrank1 = atoi(t);
392 
393  t = _sion_getenv("SION_DEBUG_RANK1");
394  if (t)
395  _sion_debug_debrank1 = atoi(t);
396 
397  t = _sion_getenv("SION_DEBUG_RANK2");
398  if (t)
399  _sion_debug_debrank2 = atoi(t);
400 
401  t = _sion_getenv("SION_DEBUG");
402  if (t) {
403  _sion_debug_fn = (char *) t;
404  }
405 
406  t = _sion_getenv("SION_DEBUG_MASK");
407  if (t)
408  _sion_debug_debmask = atoi(t);
409 
410  t = _sion_getenv("SION_DEBUG_SILENT");
411  if (t)
412  _sion_debug_silent = atoi(t);
413 
414  _sion_debug_isinit=1;
415  _sion_unlock();
416  }
417 
418  if (_sion_debug_fn) {
419  _sion_debug_isdebug[threadid] = 1; /* set debug mode if SION_DEBUG ist set */
420  }
421 
422  if ((_sion_debug_debrank1 >= 0) && (_sion_debug_debrank2 >= 0)) {
423  if ((_sion_debug_myrank[threadid] != _sion_debug_debrank1) && (_sion_debug_myrank[threadid] != _sion_debug_debrank2))
424  _sion_debug_isdebug[threadid] = 0;
425  }
426  else if (_sion_debug_debrank1 >= 0) {
427  if (_sion_debug_myrank[threadid] != _sion_debug_debrank1)
428  _sion_debug_isdebug[threadid] = 0;
429  }
430 
431  if ((_sion_debug_debrank1 == -2) && (_sion_debug_debrank2 == -2)) {
432  _sion_debug_isdebug[threadid] = 1;
433  }
434  if (_sion_debug_isdebug[threadid]) {
435 
436  if ((_sion_debug_fn == 0) || (strlen(_sion_debug_fn) == 0) || !strcmp(_sion_debug_fn, "stderr")) {
437  _sion_debug_out[threadid] = stderr;
438  }
439  else if (!strcmp(_sion_debug_fn, "stdout")) {
440  _sion_debug_out[threadid] = stdout;
441  }
442  else {
443  filename=malloc((strlen(_sion_debug_fn) + 1 + 10) * sizeof(char));
444  sprintf(filename, "%s.%05d", _sion_debug_fn, _sion_debug_myrank[threadid]);
445 
446  if (!(_sion_debug_out[threadid] = fopen(filename, "a"))) {
447  fprintf(_sion_debug_out[threadid], "sion_dprintf: failed to open '%s' for writing\n", filename);
448  rvalue = 0;
449  }
450 
451  if( rvalue && ((_sion_debug_out[threadid] != stdout) && (_sion_debug_out[threadid] != stderr)) && (!_sion_debug_silent) )
452  fprintf(stderr, "Writing debug output to %s\n", filename);
453 
454  }
455 
456  if (filename) free(filename);
457 
458  /* print a warning (to avoid using accidentally
459  a library that is full of DPRINTFs) */
460 #ifdef SION_DEBUG_EXTREME
461  fprintf(stderr, "Warning: you are using a version of SION that is configured with --with-debug (current debug-mask is %d)\n", _sion_debug_debmask);
462 #endif
463 
464  } /* _sion_debug_isdebug[threadid] */
465 
466  } /* _sion_debug_first[threadid] */
467 
468  }
469 
470  return rvalue;
471 }
callback wrappers for OMP thread safe fd manipulation
int sion_dprintfp(int mask, const char *callfunction, int rank, const char *format,...)
Print debugging info formating the message like printf and including the name of the calling function...
Definition: sion_debug.c:205
FILE * sion_get_dfile(void)
Definition: sion_debug.c:277
int _sion_debug_init(void)
initialize the debug environment
Definition: sion_debug.c:371
void sion_debug_on(int mask, const char *filename)
sets debug mode.
Definition: sion_debug.c:315
int sion_dprintf(int mask, const char *format,...)
Print debugging info formating the message like printf.
Definition: sion_debug.c:179
void sion_dclose(void)
Definition: sion_debug.c:289
char * _sion_getenv(const char *name)