3 #define HOST_NAME_MAX 100 41 #ifdef __INTEL_COMPILER 49 #elif defined(PMAPI_P6) 52 #elif defined(PMAPI_P5_PLUS) 60 #if defined(SV2) || defined(XD1) || defined(XT3) 63 #define MAX_COUNTERS 6 67 #pragma options opt=3 halt=e 77 static char *
TimeStr(
char *s,
int slen);
81 #if !defined(CACHELINESIZE) 84 #define CACHELINESIZE 128 86 #define CACHELINESIZE 64 97 #pragma cdir options -Nv -Csopt 98 extern void necsx_trbk_(
const char *msg,
int msglen);
101 #if defined(LINUX) && !defined(XT3) && !defined(XD1) && !defined(CYGWIN) 103 #if defined(__GNUC__) && !defined(NO_TRAPFPE) 105 #define _GNU_SOURCE 1 107 #include <mingw/fenv.h> 133 #if (!defined(LINUX) || defined(CYGWIN) || defined(NO_TRAPFPE)) && defined(__GNUC__) 139 #ifndef drhook_harakiri_timeout_default 140 #define drhook_harakiri_timeout_default 500 171 #define callpath_indent_default 2 173 #define callpath_depth_default 50 206 unsigned long long int calls[2];
207 double last_curheap_MB;
209 char pad[CACHELINESIZE - (2*
sizeof(
unsigned long long int) + 2*
sizeof(
double))];
220 #define DRHOOK_STRBUF 1000 224 #define SIG_EXTRA_ARGS 225 #define SIG_PASS_EXTRA_ARGS 227 #define SIG_EXTRA_ARGS , siginfo_t *sigcode, void *sigcontextptr 228 #define SIG_PASS_EXTRA_ARGS , sigcode, sigcontextptr 234 #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) 237 #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) 240 #define ABS(x) ( (x) >= 0 ? (x) : -(x) ) 242 #define strequ(s1,s2) ((void *)s1 && (void *)s2 && strcmp(s1,s2) == 0) 243 #define strnequ(s1,s2,n) ((void *)s1 && (void *)s2 && memcmp(s1,s2,n) == 0) 245 extern long long int getstk_();
247 extern long long int gethwm_();
249 extern long long int getrss_();
255 extern long long int getpag_();
260 extern double flop_();
268 extern long long int irtc();
269 #define WALLTIME() ((double)(irtc() - irtc_start)*1.0e-9) 270 #define CPUTIME() util_cputime_() 271 #elif defined(CRAYXT) 273 #include <catamount/dclock.h> 275 #define WALLTIME() (dclock() - dclock_start) 276 #define CPUTIME() WALLTIME() 279 #include <intrinsics.h> 281 #if defined(XD1) || defined(XT3) 282 extern long long int irtc_();
285 #if defined(SV2) || defined(XD1) || defined(XT3) 290 #define WALLTIME() ((double)(_rtc() - irtc_start)*my_inv_irtc_rate) 292 #define WALLTIME() ((double)(irtc_() - irtc_start)*my_inv_irtc_rate) 294 #define CPUTIME() util_cputime_() 296 #define WALLTIME() util_walltime_() 297 #define CPUTIME() util_cputime_() 306 extern void LinuxTraceBack(
const char *prefix,
const char *timestr,
void *sigcontextptr);
313 unsigned long long int ull;
318 unsigned short name_len;
319 const equivalence_t *callpath;
321 unsigned int callpath_fullhash;
322 unsigned short status;
323 unsigned long long int calls;
324 long long int hwm, maxrss, rssnow, stack,
maxstack, paging;
325 double wall_in, delta_wall_all, delta_wall_child;
326 double cpu_in, delta_cpu_all, delta_cpu_child;
328 unsigned char hpm_stopped, counter_stopped;
329 double this_delta_wall_child;
330 double avg_mipsrate, avg_mflops;
331 unsigned long long int hpm_calls;
332 double mip_count_in, mflop_count_in;
333 long long int *counter_in, *counter_sum;
337 long long int sizeinfo;
338 long long int min_sizeinfo, max_sizeinfo;
340 long long int mem_seenmax;
341 long long int mem_child, mem_curdelta;
342 long long int maxmem_selfdelta, maxmem_alldelta;
343 long long int mem_maxhwm, mem_maxrss, mem_maxstk, mem_maxpagdelta;
344 long long int paging_in;
345 unsigned long long int alloc_count, free_count;
358 struct sigaction new;
359 struct sigaction old;
365 void (*func1args)(
int sig);
366 void (*func3args)(
int sig SIG_EXTRA_ARGS);
373 unsigned long long int calls;
374 double percall_ms_self;
375 double percall_ms_total;
376 double mipsrate, mflops, divpc;
381 unsigned char is_max;
384 long long int sizeinfo;
385 long long int min_sizeinfo, max_sizeinfo;
386 double sizespeed, sizeavg;
387 const equivalence_t *callpath;
394 long long int children;
395 long long int hwm, rss, stk, pag, leaked;
396 unsigned long long int calls, alloc_count, free_count;
400 long long int *maxval;
401 unsigned char is_max;
404 const equivalence_t *callpath;
408 #define MAX_WATCH_FIRST_NBYTES 8 414 int abort_if_changed;
417 int watch_first_nbytes;
418 char first_nbytes[MAX_WATCH_FIRST_NBYTES];
462 #define PREFIX(tid) (ec_drhook && tid >= 1 && tid <= numthreads) ? ec_drhook[tid-1].s : "" 463 #define TIDNSIGS(tid) (ec_drhook && tid >= 1 && tid <= numthreads) ? ec_drhook[tid-1].nsigs : -1 464 #define TIMESTR(tid) (timestr_len > 0 && ec_drhook && tid >= 1 && tid <= numthreads) ? TimeStr(ec_drhook[tid-1].timestr,timestr_len) : "" 465 #define FFL __FUNCTION__,__FILE__,__LINE__ 468 #define SYS_gettid __NR_gettid 472 pid_t tid = syscall(SYS_gettid);
477 #if !defined(NCALLSTACK) 478 #ifdef PARKIND1_SINGLE 480 #define NCALLSTACK 64 488 #define HASHSIZE(n) ((unsigned int)1<<(n)) 489 #define HASHMASK(n) (HASHSIZE(n)-1) 512 #define stopstart_hpm(tid, pstop, pstart) 513 #define stop_only_hpm(tid, pstop) 514 #define init_hpm(tid) 515 #define mflops_hpm(keyptr) 0 516 #define mips_hpm(keyptr) 0 517 #define divpc_hpm(keyptr) 0 518 #define mflop_count(keyptr) 0 519 #define mip_count(keyptr) 0 526 struct timespec req, rem;
529 return nanosleep(&req, &rem);
534 static void dump_file(
const char *pfx,
int tid,
int sig,
int nsigs,
const char filename[])
539 char *tst = TIMESTR(tid);
540 if (sig > 0 && nsigs >= 1) {
542 "%s %s [%s@%s:%d] Developer option shows content of the file '%s', signal#%d, nsigs = %d\n",
543 pfx,tst,FFL,filename,sig,nsigs);
547 "%s %s [%s@%s:%d] Developer option shows content of the file '%s'\n",
548 pfx,tst,FFL,filename);
550 fp = fopen(filename,
"r");
552 while (fgets(in,
sizeof(in),fp) == in) {
553 fprintf(stderr,
"%s %s [%s@%s:%d] %s",pfx,tst,FFL,in);
562 static void dump_hugepages(
int enforce,
const char *pfx,
int tid,
int sig,
int nsigs)
565 if (enforce || tid == 1) {
566 static double next_scheduled = -1;
567 double wt = WALLTIME();
568 if (enforce || wt > next_scheduled) {
569 const int kcomm = -1;
570 const int ftnunitno = 0;
572 ec_cray_meminfo_(&ftnunitno,pfx,&kcomm,strlen(pfx));
575 dump_file(pfx,tid,sig,nsigs,
"/proc/buddyinfo");
576 dump_file(pfx,tid,sig,nsigs,
"/proc/meminfo");
593 if (sig >= 1 && sig <= NSIG) {
594 unsigned long long int hardlimit = 0;
595 struct sigaction sa = { 0 };
596 sa.sa_handler = SIG_DFL;
597 sigemptyset(&sa.sa_mask);
602 sigaction(sig, &sa, NULL);
606 char *pfx = PREFIX(tid);
608 if (unlimited_corefile && rc == 0)
snprintf(buf,
sizeof(buf),
" -- hardlimit for core file is now %llu (0x%llx)", hardlimit, hardlimit);
611 "Enabled default signal handler (SIG_DFL) for signal#%d%s\n",
612 pfx,TIMESTR(tid),FFL,
624 size_t size1 = MAX(1,size);
625 void *p = malloc(size1);
628 "***Error in malloc_drhook(): Unable to allocate space for %lld bytes\n",
629 (
long long int)size1);
640 size_t n = nmemb *
size;
648 #define free_drhook(x) { if (x) { free(x); x = NULL; } } 657 unsigned int maxdepth;
681 static const unsigned int inc = 64;
682 unsigned int idx, *Index = key;
692 if (idx >= c->maxdepth) {
694 unsigned int maxdepth = idx + inc;
695 char *pfx = PREFIX(tid);
698 "Call stack index %u out of range [0,%u) : extending the range to [0,%u) for this thread\n",
699 pfx,TIMESTR(tid),FFL,
700 idx,c->maxdepth,maxdepth);
702 memcpy(kptr,c->keyptr,c->maxdepth *
sizeof(
drhook_key_t *));
703 free_drhook(c->keyptr);
705 c->maxdepth = maxdepth;
707 if (idx >= c->maxdepth) {
708 char *pfx = PREFIX(tid);
711 "Call stack index %u still out of range [0,%u). Aborting ...\n",
712 pfx,TIMESTR(tid),FFL,
716 c->keyptr[idx] = keyptr;
722 char *pfx = PREFIX(tid);
725 "Invalid index to call stack %u : out of range [0,%u). Expecting the exact value of %u\n",
726 pfx,TIMESTR(tid),FFL,
727 idx,c->maxdepth,*Index);
730 keyptr = c->keyptr[idx];
765 const int bufsize = 64;
768 strftime(buf, bufsize,
"%Y%m%d %H%M%S", localtime(&tp));
781 strftime(buf,
sizeof(buf),
"%Y%m%d:%H%M%S", localtime(&tp));
782 snprintf(s,slen,
"[%s:%lld:%.3f]",buf,(
long long int)tp,WALLTIME());
792 unsigned int hashval;
794 for (hashval = 0; s_len>0 ; s++, s_len--) {
795 unsigned char c = islower(*s) ?
toupper(*s) : *s;
796 hashval = (hashval<<4)^(hashval>>28)^(c);
800 for (hashval = s_len; s_len>0 ; s_len--) {
801 hashval = (hashval<<4)^(hashval>>28)^(*s++);
804 hashval = (hashval ^ (hashval>>10) ^ (hashval>>20)) &
hashmask;
812 const equivalence_t *callpath,
int callpath_len,
813 unsigned int *fullhash)
815 unsigned int hashval;
816 for (hashval = inithash; callpath_len>0 ; callpath++, callpath_len--) {
817 hashval = (hashval<<4)^(hashval>>28)^(callpath->ull);
819 if (fullhash) *fullhash = hashval;
820 hashval = (hashval ^ (hashval>>10) ^ (hashval>>20)) &
hashmask;
831 while (treeptr->active) {
832 if (!treeptr->next) {
834 treeptr->next->prev = treeptr;
836 treeptr = treeptr->next;
838 treeptr->keyptr = keyptr;
840 thiscall[tid-1] = treeptr;
844 if (!kptr->hpm_stopped) {
846 treeptr->prev ? treeptr->prev->keyptr : NULL,
848 kptr->this_delta_wall_child = 0;
852 fprintf(stderr,
"insert[%.*s@%d]: this_delta_wall_child=%.15g, mip#%.15g, mflop#%.15g\n",
853 kptr->name_len,kptr->name,
854 tid,kptr->this_delta_wall_child,
855 kptr->mip_count_in,kptr->mflop_count_in);
860 treeptr->prev ? treeptr->prev->keyptr : NULL );
871 const double *delta_wall,
const double *delta_cpu)
875 if (treeptr->active && treeptr->keyptr == keyptr) {
881 parent_keyptr->delta_wall_child += (*delta_wall);
883 if (
opt_hpmprof) parent_keyptr->this_delta_wall_child += (*delta_wall);
887 parent_keyptr->delta_cpu_child += (*delta_cpu);
898 parent_keyptr->mem_child = MAX(parent_keyptr->mem_child, keyptr->maxmem_alldelta);
907 thiscall[tid-1] = treeptr->prev;
910 thiscall[tid-1] = calltree[tid-1];
915 if (!kptr->hpm_stopped) {
916 double this_delta_wall_self = *delta_wall - kptr->this_delta_wall_child;
919 thiscall[tid-1]->keyptr);
922 fprintf(stderr,
"remove[%.*s@%d]: this_delta_wall_self=%.15g i.e. %.15g - %.15g",
923 kptr->name_len,kptr->name,
924 tid,this_delta_wall_self,
925 *delta_wall,kptr->this_delta_wall_child);
927 if (this_delta_wall_self > 0) {
928 long long int hpm_calls = ++kptr->hpm_calls;
929 double mipsrate, mflops;
930 kptr->mip_count_in =
mip_count(kptr) - kptr->mip_count_in;
931 kptr->mflop_count_in =
mflop_count(kptr) - kptr->mflop_count_in;
932 mipsrate = kptr->mip_count_in/this_delta_wall_self;
933 kptr->avg_mipsrate = ((hpm_calls-1)*kptr->avg_mipsrate + mipsrate)/hpm_calls;
934 mflops = kptr->mflop_count_in/this_delta_wall_self;
935 kptr->avg_mflops = ((hpm_calls-1)*kptr->avg_mflops + mflops)/hpm_calls;
938 ", mip#%.15g, mflop#%.15g : mipsrate=%.15g, avg=%.15g; mflops=%.15g, avg=%.15g",
939 kptr->mip_count_in,kptr->mflop_count_in,
940 mipsrate, kptr->avg_mipsrate,
941 mflops, kptr->avg_mflops);
945 fprintf(stderr,
"\n");
957 curkeyptr[tid-1] = thiscall[tid-1]->keyptr;
960 curkeyptr[tid-1] = NULL;
979 keyptr->maxstack = MAX(keyptr->maxstack,stk);
993 keyptr->paging_in = keyptr->paging;
996 long long int alldelta = keyptr->mem_curdelta + keyptr->mem_child;
997 if (alldelta > keyptr->maxmem_alldelta) keyptr->maxmem_alldelta = alldelta;
998 if (keyptr->paging - keyptr->paging_in > keyptr->mem_maxpagdelta)
999 keyptr->mem_maxpagdelta = keyptr->paging - keyptr->paging_in;
1001 if (keyptr->hwm > keyptr->mem_maxhwm) keyptr->mem_maxhwm = keyptr->hwm;
1002 if (keyptr->maxrss > keyptr->mem_maxrss) keyptr->mem_maxrss = keyptr->maxrss;
1003 if (keyptr->maxstack > keyptr->mem_maxstk) keyptr->mem_maxstk = keyptr->maxstack;
1021 if (sig == SIGFPE) {
1023 int ret = fp_trap(FP_TRAP_FASTMODE);
1024 if ((ret == FP_TRAP_UNIMPL) || (ret == FP_TRAP_ERROR)) {
1027 "flptrap(): Call to 'fp_trap' in signal_trap failed (return code = %d)\n (line %d in file %s)\n",
1028 ret, __LINE__, __FILE__);
1032 fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
1035 #elif defined(__GNUC__) && !defined(NO_TRAPFPE) 1039 if (sig == SIGFPE) {
1059 #define CATCHSIG(x) {\ 1060 drhook_sig_t *sl = &siglist[x];\ 1061 if (sl->active == 0) {\ 1062 drhook_sigfunc_t u;\ 1063 u.func3args = signal_drhook;\ 1065 sigemptyset(&sl->new.sa_mask);\ 1066 sl->new.sa_handler = u.func1args;\ 1067 sl->new.sa_flags = SA_SIGINFO;\ 1068 sigaction(x,&sl->new,&sl->old);\ 1069 trapfpe_treatment(x,silent); \ 1070 if (!silent && myproc == 1) {\ 1071 int tid = get_thread_id_(); \ 1072 char *pfx = PREFIX(tid); \ 1074 "%s %s [%s@%s:%d] DR_HOOK also catches signal#%d : New handler '%s' installed at %p (old at %p)\n", \ 1075 pfx,TIMESTR(tid),FFL, \ 1076 x, "signal_drhook", sl->new.sa_handler, sl->old.sa_handler); \ 1084 char *env = getenv(
"DR_HOOK_CATCH_SIGNALS");
1085 if (!silent &&
myproc == 1) {
1087 char *pfx = PREFIX(tid);
1089 "%s %s [%s@%s:%d] DR_HOOK_CATCH_SIGNALS=%s\n",
1090 pfx,TIMESTR(tid),FFL,
1091 env ? env :
"<undef>");
1094 const char delim[] =
", \t/";
1096 p = strtok(s,delim);
1099 if (sig >= 1 && sig <= NSIG) {
1102 else if (sig == -1) {
1104 for (j=1; j<=NSIG; j++) {
1109 p = strtok(NULL,delim);
1120 if (sig == SIGFPE) {
1121 #if defined(__GNUC__) && !defined(NO_TRAPFPE) 1123 char *pfx = PREFIX(tid);
1125 if (!silent &&
myproc == 1) {
1127 "%s %s [%s@%s:%d] DR_HOOK enables SIGFPE-related floating point trapping since DRHOOK_TRAPFPE=%d\n",
1128 pfx,TIMESTR(tid),FFL,
1134 if (!silent &&
myproc == 1) {
1136 "%s %s [%s@%s:%d] DR_HOOK turns SIGFPE-related floating point trapping off since DRHOOK_TRAPFPE=%d\n",
1137 pfx,TIMESTR(tid),FFL,
1151 char *env = getenv(
"DR_HOOK_RESTORE_DEFAULT_SIGNALS");
1152 if (!silent &&
myproc == 1) {
1154 char *pfx = PREFIX(tid);
1156 "%s %s [%s@%s:%d] DR_HOOK_RESTORE_DEFAULT_SIGNALS=%s\n",
1157 pfx,TIMESTR(tid),FFL,
1158 env ? env :
"<undef>");
1162 const char delim[] =
", \t/";
1164 p = strtok(s,delim);
1167 if (sig >= 1 && sig <= NSIG) {
1169 if (sl->active == 0) {
1176 else if (sig == -1) {
1178 for (j=1; j<=NSIG; j++) {
1180 if (sl->active == 0) {
1189 p = strtok(NULL,delim);
1200 char *env = getenv(
"DR_HOOK_IGNORE_SIGNALS");
1201 if (!silent &&
myproc == 1) {
1203 char *pfx = PREFIX(tid);
1205 "%s %s [%s@%s:%d] DR_HOOK_IGNORE_SIGNALS=%s\n",
1206 pfx,TIMESTR(tid),FFL,
1207 env ? env :
"<undef>");
1211 char *pfx = PREFIX(tid);
1212 const char delim[] =
", \t/";
1214 p = strtok(s,delim);
1217 if (sig >= 1 && sig <= NSIG) {
1219 if (!silent &&
myproc == 1) {
1221 "%s %s [%s@%s:%d] DR_HOOK ignores signal#%d altogether\n",
1222 pfx,TIMESTR(tid),FFL,
1227 else if (sig == -1) {
1229 for (j=1; j<=NSIG; j++) {
1231 if (!silent &&
myproc == 1) {
1233 "%s %s [%s@%s:%d] DR_HOOK ignores signal#%d altogether\n",
1234 pfx,TIMESTR(tid),FFL,
1241 p = strtok(NULL,delim);
1249 #if (defined(LINUX) || defined(SUN4)) && !defined(XT3) && !defined(XD1) && !defined(_CRAYC) 1256 char *pfx = PREFIX(it);
1259 if (is_set && who == it) {
1260 fprintf(stderr,
"%s %s [%s@%s:%d] Received (another) signal#%d (%s)\n",
1261 pfx,TIMESTR(it),FFL,
1263 fprintf(stderr,
"%s %s [%s@%s:%d] Recursive calls by the same thread#%d not allowed. Bailing out\n",
1264 pfx,TIMESTR(it),FFL,
1270 fprintf(stderr,
"%s %s [%s@%s:%d] Received signal#%d(%s) : sigcontextptr=%p\n",
1271 pfx,TIMESTR(it),FFL,
1272 sig,sl->name,sigcontextptr);
1282 #define SETSIG5(x,ignore_flag,handler_name,preserve_old,xstr) { \ 1283 drhook_sig_t *sl = &siglist[x]; \ 1284 if (sl->active == 0) { \ 1285 drhook_sigfunc_t u; \ 1286 u.func3args = handler_name; \ 1288 strcpy(sl->name,xstr); \ 1289 sigemptyset(&sl->new.sa_mask); \ 1290 sl->new.sa_handler = u.func1args; \ 1291 sl->new.sa_flags = SA_SIGINFO; \ 1292 sigaction(x,&sl->new,preserve_old ? &sl->old : NULL); \ 1293 sl->ignore_atexit = ignore_flag; \ 1294 trapfpe_treatment(x,silent); \ 1295 if (!silent && myproc == 1) { \ 1296 int tid = get_thread_id_(); \ 1297 char *pfx = PREFIX(tid); \ 1298 const char fmt[] = "%s %s [%s@%s:%d] New signal handler '%s' for signal#%d (%s) at %p (old at %p)\n"; \ 1299 fprintf(stderr,fmt, \ 1300 pfx,TIMESTR(tid),FFL, \ 1303 sl->new.sa_handler, \ 1304 preserve_old ? sl->old.sa_handler : NULL); \ 1309 #define SETSIG(x,ignore_flag) SETSIG5(x,ignore_flag,signal_drhook,1,#x) 1311 #define JSETSIG(x,ignore_flag) { \ 1312 drhook_sig_t *sl = &siglist[x]; \ 1313 drhook_sigfunc_t u; \ 1315 u.func3args = signal_harakiri; \ 1317 strcpy(sl->name,#x); \ 1318 sigemptyset(&sl->new.sa_mask); \ 1319 sl->new.sa_handler = u.func1args; \ 1320 sl->new.sa_flags = SA_SIGINFO; \ 1321 sigaction(x,&sl->new,&sl->old); \ 1322 sl->ignore_atexit = ignore_flag; \ 1323 trapfpe_treatment(x,0); \ 1325 int tid = get_thread_id_(); \ 1326 char *pfx = PREFIX(tid); \ 1327 const char fmt[] = "%s %s [%s@%s:%d] Harakiri signal handler '%s' for signal#%d (%s) installed at %p (old at %p)\n"; \ 1328 fprintf(stderr,fmt, \ 1329 pfx,TIMESTR(tid),FFL, \ 1330 "signal_harakiri", \ 1332 sl->new.sa_handler, \ 1333 sl->old.sa_handler); \ 1337 #if defined(RS6K) && defined(__64BIT__) 1338 #define DRH_STRUCT_RLIMIT struct rlimit64 1339 #define DRH_GETRLIMIT getrlimit64 1340 #define DRH_SETRLIMIT setrlimit64 1342 #define DRH_STRUCT_RLIMIT struct rlimit 1343 #define DRH_GETRLIMIT getrlimit 1344 #define DRH_SETRLIMIT setrlimit 1358 DRH_STRUCT_RLIMIT r;
1359 if (DRH_GETRLIMIT(RLIMIT_CORE, &r) == 0) {
1360 r.rlim_cur = r.rlim_max;
1361 if (DRH_SETRLIMIT(RLIMIT_CORE, &r) == 0) {
1379 signal(sig, SIG_IGN);
1380 signal(SIGABRT, SIG_DFL);
1384 char *pfx = PREFIX(tid);
1386 "%s %s [%s@%s:%d] Received signal#%d and now calling abort() ...\n",
1387 pfx,TIMESTR(tid),FFL,
1395 _exit(128+ABS(sig));
1402 char const digit[] =
"0123456789";
1404 long long int shifter;
1412 shifter = shifter/10;
1431 int fd = fileno(stderr);
1433 int nsigs = TIDNSIGS(tid);
1434 char *pfx = PREFIX(tid);
1440 strcat(s,__FUNCTION__);
1445 strcat(s,
"] [epoch=");
1448 strcat(s,
"] Terminating process to avoid hangs due to signal#");
1450 strcat(s,
" by raising signal SIGKILL = ");
1452 strcat(s,
", nsigs = ");
1455 write(fd,s,strlen(s));
1458 _exit(128+ABS(sig));
1466 char *pfx = PREFIX(tid);
1469 sigset_t newmask, oldmask;
1472 signal(sig, SIG_IGN);
1477 #pragma omp critical 1485 if (ec_drhook && tid >= 1 && tid <=
numthreads) ec_drhook[tid-1].nsigs = nsigs;
1507 long long int hwm =
gethwm_();
1510 long long int pag =
getpag_();
1513 maxstack /= 1048576;
1515 "%s %s [%s@%s:%d] Received signal#%d (%s) :: %lldMB (heap)," 1516 " %lldMB (maxrss), %lldMB (maxstack), %lld (paging), nsigs = %d\n",
1517 pfx,TIMESTR(tid),FFL,
1518 sig, sl->name, hwm, rss, maxstack, pag, nsigs);
1520 "%s %s [%s@%s:%d] Also activating Harakiri-alarm (SIGALRM=%d) to expire after %ds elapsed to prevent hangs, nsigs = %d\n",
1521 pfx,TIMESTR(tid),FFL,
1527 else if (nsigs > 1) {
1532 "%s %s [%s@%s:%d] Calling signal_harakiri upon receipt of signal#%d" 1533 " after %ds spin, nsigs = %d\n",
1534 pfx,TIMESTR(tid),FFL,
1570 const int ftnunitno = 0;
1571 const int print_option = 2;
1577 pid_t unixtid =
gettid();
1579 snprintf(filename,
sizeof(filename),
"/proc/%ld/smaps",(
long)unixtid);
1584 "%s %s [%s@%s:%d] Starting DrHook backtrace for signal#%d, nsigs = %d\n",
1585 pfx,TIMESTR(tid),FFL,
1599 if (sig != SIGABRT && sig != SIGTERM) {
1601 xl__sigdump(sig SIG_PASS_EXTRA_ARGS);
1606 #if (defined(LINUX) || defined(SUN4)) && !defined(XT3) && !defined(XD1) 1611 #if (defined(LINUX) || defined(SUN4)) && !defined(XT3) && !defined(XD1) && !defined(_CRAYC) 1616 #ifdef __INTEL_COMPILER 1626 #if defined(SA_SIGINFO) && SA_SIGINFO > 0 1627 _TraceCalls(sigcontextptr);
1632 "%s %s [%s@%s:%d] DrHook backtrace done for signal#%d, nsigs = %d\n",
1633 pfx,TIMESTR(tid),FFL,
1642 int restored = 0, tdiff;
1647 sl->old.sa_handler != SIG_DFL &&
1648 sl->old.sa_handler != SIG_IGN &&
1649 sl->old.sa_handler != u.func1args) {
1650 u.func1args = sl->old.sa_handler;
1666 #if defined(SIGXFSZ) 1670 "%s %s [%s@%s:%d] Resetting SIGSEGV (%d) to " 1671 "default signal handler (SIG_DFL) before calling ATP for signal#%d, nsigs = %d\n",
1672 pfx,TIMESTR(tid),FFL,
1683 "%s %s [%s@%s:%d] Calling previous signal handler at %p for signal#%d, nsigs = %d\n",
1684 pfx,TIMESTR(tid),FFL,
1685 u.func1args,sig,nsigs);
1688 u.func3args(sig SIG_PASS_EXTRA_ARGS);
1693 "%s %s [%s@%s:%d] Returned from previous signal handler" 1694 " (at %p, signal#%d, time taken = %ds), nsigs = %d\n",
1695 pfx,TIMESTR(tid),FFL,
1696 u.func1args,sig,tdiff,nsigs);
1705 "%s %s [%s@%s:%d] Before aborting (signal#%d) spin %ds (incl. grace %ds)" 1706 " to give ATP time to write all #%d core file(s), nsigs = %d\n",
1707 pfx,TIMESTR(tid),FFL,
1713 if (sig != SIGABRT && sig != SIGTERM) {
1716 "%s %s [%s@%s:%d] DrHook calls abort() and attempts to dump core (signal#%d), nsigs = %d\n",
1717 pfx,TIMESTR(tid),FFL,
1727 "%s %s [%s@%s:%d] Not configured (DR_HOOK_PROPAGATE_SIGNALS=%d) or " 1728 "can't call previous signal handler (for signal#%d) in the chain at %p, nsigs = %d\n",
1729 pfx,TIMESTR(tid),FFL,
1731 sl->old.sa_handler,nsigs);
1737 int errcode = 128 + ABS(sig);
1739 fprintf(stderr,
"%s %s [%s@%s:%d] Error _exit(%d) upon receipt of signal#%d, nsigs = %d\n",
1740 pfx,TIMESTR(tid),FFL,
1758 static char s[] =
"DR_HOOK_NOT_MPI=1";
1768 char *env = getenv(
"DR_HOOK_SILENT");
1769 int silent = env ? atoi(env) : 0;
1775 if (!enforce && (
myproc < 1 ||
nproc < 0))
return;
1779 env = getenv(
"DR_HOOK_INIT_SIGNALS");
1780 if (env && *env ==
'0') {
1786 char hostname[HOST_NAME_MAX];
1789 ntids = omp_get_max_threads();
1793 slen =
sizeof(ec_drhook[0].s);
1795 if (gethostname(hostname,
sizeof(hostname)) != 0) strcpy(hostname,
"unknown");
1797 fprintf(stderr,
"[EC_DRHOOK:hostname:myproc:omptid:pid:unixtid] [YYYYMMDD:HHMMSS:epoch:walltime] [function@file:lineno] -- Max OpenMP threads = %d\n",ntids);
1799 #pragma omp parallel num_threads(ntids) 1803 pid_t unixtid =
gettid();
1804 snprintf(ec_drhook[j].s,slen,
"[EC_DRHOOK:%s:%d:%d:%lld:%lld]",
1806 (
long long int)
pid, (
long long int)unixtid);
1809 env = getenv(
"ATP_ENABLED");
1812 env = getenv(
"ATP_MAX_CORES");
1814 env = getenv(
"ATP_MAX_ANALYSIS_TIME");
1816 env = getenv(
"ATP_IGNORE_SIGTERM");
1818 if (!silent &&
myproc == 1) {
1820 char *pfx = PREFIX(tid);
1821 fprintf(stderr,
"%s %s [%s@%s:%d] ATP_ENABLED=%d\n",pfx,TIMESTR(tid),FFL,
atp_enabled);
1822 fprintf(stderr,
"%s %s [%s@%s:%d] ATP_MAX_CORES=%d\n",pfx,TIMESTR(tid),FFL,
atp_max_cores);
1823 fprintf(stderr,
"%s %s [%s@%s:%d] ATP_MAX_ANALYSIS_TIME=%d\n",pfx,TIMESTR(tid),FFL,
atp_max_analysis_time);
1824 fprintf(stderr,
"%s %s [%s@%s:%d] ATP_IGNORE_SIGTERM=%d\n",pfx,TIMESTR(tid),FFL,
atp_ignore_sigterm);
1828 for (j=1; j<=NSIG; j++) {
1830 sprintf(sl->name,
"DR_HOOK_SIG#%d", j);
1832 sl->ignore_atexit = 0;
1842 #if defined(SIGSTKFLT) 1843 SETSIG(SIGSTKFLT,0);
1866 #if defined(SIGXFSZ) 1869 #if defined(SIGDANGER) 1870 SETSIG(SIGDANGER,1);
1879 #if defined(SIGCORE) 1882 #if defined(SIGDEAD) 1885 #if defined(SIGXMEM) 1888 #if defined(SIGXDSZ) 1891 #if defined(SIGMEM32) 1894 #if defined(SIGNMEM) 1897 #if defined(SIGXABT) 1938 sprintf(s,
"%s-mem",p);
1950 int random_number = rand();
1966 if (Myproc)
myproc = *Myproc;
1967 if (Nproc)
nproc = *Nproc;
1971 #define OPTPRINT(fp,...) if (fp) fprintf(fp,__VA_ARGS__) 1979 int tid, ienv, newline;
1980 static int processed = 0;
1981 if (processed)
return;
1985 env = getenv(
"DR_HOOK_SHOW_PROCESS_OPTIONS");
1986 ienv = env ? atoi(env) : 1;
1987 if (ienv == -1 || ienv ==
myproc) fp = stderr;
1988 if (fp) pfx = PREFIX(tid);
1990 OPTPRINT(fp,
"%s %s [%s@%s:%d] fp = %p\n",pfx,TIMESTR(tid),FFL,fp);
1992 env = getenv(
"DR_HOOK_ALLOW_COREDUMP");
1997 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_ALLOW_COREDUMP=%d\n",pfx,TIMESTR(tid),FFL,
allow_coredump);
1999 unsigned long long int hardlimit = 0;
2002 OPTPRINT(fp,
"%s %s [%s@%s:%d] Hardlimit for core file is now %llu (0x%llx)\n",
2003 pfx,TIMESTR(tid),FFL,hardlimit,hardlimit);
2007 env = getenv(
"DR_HOOK_PROFILE");
2011 if (!strchr(env,
'%')) strcat(s,
".%d");
2015 if (
mon_out) OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_PROFILE=%s\n",pfx,TIMESTR(tid),FFL,
mon_out);
2017 env = getenv(
"DR_HOOK_PROFILE_PROC");
2021 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_PROFILE_PROC=%d\n",pfx,TIMESTR(tid),FFL,
mon_out_procs);
2023 env = getenv(
"DR_HOOK_PROFILE_LIMIT");
2027 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_PROFILE_LIMIT=%.3f\n",pfx,TIMESTR(tid),FFL,
percent_limit);
2029 env = getenv(
"DR_HOOK_FUNCENTER");
2035 env = getenv(
"DR_HOOK_FUNCEXIT");
2045 env = getenv(
"DR_HOOK_TIMELINE");
2051 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_TIMELINE=%d\n",pfx,TIMESTR(tid),FFL,
opt_timeline);
2053 env = getenv(
"DR_HOOK_TIMELINE_THREAD");
2057 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_TIMELINE_THREAD=%d\n",pfx,TIMESTR(tid),FFL,
opt_timeline_thread);
2059 env = getenv(
"DR_HOOK_TIMELINE_FORMAT");
2063 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_TIMELINE_FORMAT=%d\n",pfx,TIMESTR(tid),FFL,
opt_timeline_format);
2065 env = getenv(
"DR_HOOK_TIMELINE_UNITNO");
2069 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_TIMELINE_UNITNO=%d\n",pfx,TIMESTR(tid),FFL,
opt_timeline_unitno);
2071 env = getenv(
"DR_HOOK_TIMELINE_FREQ");
2075 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_TIMELINE_FREQ=%lld\n",pfx,TIMESTR(tid),FFL,
opt_timeline_freq);
2077 env = getenv(
"DR_HOOK_TIMELINE_MB");
2082 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_TIMELINE_MB=%g\n",pfx,TIMESTR(tid),FFL,
opt_timeline_MB);
2085 env = getenv(
"DR_HOOK_RANDOM_MEMSTAT");
2093 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_RANDOM_MEMSTAT=%d (RAND_MAX=%d)\n",pfx,TIMESTR(tid),FFL,
opt_random_memstat,RAND_MAX);
2095 env = getenv(
"DR_HOOK_HASHBITS");
2097 int value = atoi(env);
2098 if (value < 1) value = 1;
2099 else if (value > NHASHMAX) value = NHASHMAX;
2104 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_HASHBITS=%d\n",pfx,TIMESTR(tid),FFL,
nhash);
2106 env = getenv(
"DR_HOOK_NCALLSTACK");
2108 int value = atoi(env);
2109 if (value < 1) value = NCALLSTACK;
2112 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_NCALLSTACK=%d\n",pfx,TIMESTR(tid),FFL,
cstklen);
2114 env = getenv(
"DR_HOOK_HARAKIRI_TIMEOUT");
2116 int value = atoi(env);
2117 if (value < 1) value = drhook_harakiri_timeout_default;
2122 env = getenv(
"DR_HOOK_TRAPFPE");
2124 int value = atoi(env);
2127 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_TRAPFPE=%d\n",pfx,TIMESTR(tid),FFL,
drhook_trapfpe);
2129 env = getenv(
"DR_HOOK_TIMED_KILL");
2135 env = getenv(
"DR_HOOK_DUMP_SMAPS");
2142 env = getenv(
"DR_HOOK_DUMP_BUDDYINFO");
2149 env = getenv(
"DR_HOOK_DUMP_HUGEPAGES");
2152 int nel = sscanf(env,
"%d,%lf",&ienv,&freq);
2158 if (
drhook_dump_hugepages) OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_DUMP_HUGEPAGES=%d,%.6f\n",pfx,TIMESTR(tid),FFL,
2161 env = getenv(
"DR_HOOK_GENCORE");
2167 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_GENCORE=%d\n",pfx,TIMESTR(tid),FFL,
opt_gencore);
2169 env = getenv(
"DR_HOOK_GENCORE_SIGNAL");
2171 int itmp = atoi(env);
2172 if (itmp >= 1 && itmp <= NSIG && itmp != SIGABRT) {
2176 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_GENCORE_SIGNAL=%d\n",pfx,TIMESTR(tid),FFL,
opt_gencore_signal);
2179 env = getenv(
"DR_HOOK_HPMSTOP");
2187 if (isspace(*env) || *env ==
',') *env =
' ';
2190 n = sscanf(s,
"%lld %lf",&a,&b);
2193 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_HPMSTOP=%lld,%.15g\n",
2199 env = getenv(
"DR_HOOK_OPT");
2201 const char delim[] =
", \t/";
2202 char *comma =
" DR_HOOK_OPT=\"";
2206 if (islower(*p)) *p =
toupper(*p);
2209 p = strtok(s,delim);
2212 fprintf(fp,
"%s %s [%s@%s:%d]",pfx,TIMESTR(tid),FFL);
2217 if (strequ(p,
"ALL")) {
2221 OPTPRINT(fp,
"%s%s",comma,
"ALL"); comma =
",";
2223 else if (strequ(p,
"MEM") || strequ(p,
"MEMORY")) {
2227 OPTPRINT(fp,
"%s%s",comma,
"MEMORY"); comma =
",";
2229 else if (strequ(p,
"TIME") || strequ(p,
"TIMES")) {
2232 OPTPRINT(fp,
"%s%s",comma,
"TIMES"); comma =
",";
2234 else if (strequ(p,
"HWM") || strequ(p,
"HEAP")) {
2238 OPTPRINT(fp,
"%s%s",comma,
"HEAP"); comma =
",";
2240 else if (strequ(p,
"STK") || strequ(p,
"STACK")) {
2244 OPTPRINT(fp,
"%s%s",comma,
"STACK"); comma =
",";
2246 else if (strequ(p,
"RSS")) {
2250 OPTPRINT(fp,
"%s%s",comma,
"RSS"); comma =
",";
2252 else if (strequ(p,
"PAG") || strequ(p,
"PAGING")) {
2256 OPTPRINT(fp,
"%s%s",comma,
"PAGING"); comma =
",";
2258 else if (strequ(p,
"WALL") || strequ(p,
"WALLTIME")) {
2261 OPTPRINT(fp,
"%s%s",comma,
"WALLTIME"); comma =
",";
2263 else if (strequ(p,
"CPU") || strequ(p,
"CPUTIME")) {
2266 OPTPRINT(fp,
"%s%s",comma,
"CPUTIME"); comma =
",";
2268 else if (strequ(p,
"CALLS") || strequ(p,
"COUNT")) {
2270 OPTPRINT(fp,
"%s%s",comma,
"CALLS"); comma =
",";
2272 else if (strequ(p,
"MEMPROF")) {
2279 OPTPRINT(fp,
"%s%s",comma,
"MEMPROF"); comma =
",";
2281 else if (strequ(p,
"PROF") || strequ(p,
"WALLPROF")) {
2286 OPTPRINT(fp,
"%s%s",comma,
"WALLPROF"); comma =
",";
2288 else if (strequ(p,
"CPUPROF")) {
2293 OPTPRINT(fp,
"%s%s",comma,
"CPUPROF"); comma =
",";
2295 else if (strequ(p,
"HPM") || strequ(p,
"HPMPROF") || strequ(p,
"MFLOPS")) {
2301 OPTPRINT(fp,
"%s%s",comma,
"HPMPROF"); comma =
",";
2303 else if (strequ(p,
"TRIM")) {
2305 OPTPRINT(fp,
"%s%s",comma,
"TRIM"); comma =
",";
2307 else if (strequ(p,
"SELF")) {
2309 OPTPRINT(fp,
"%s%s",comma,
"SELF"); comma =
",";
2311 else if (strequ(p,
"NOSELF")) {
2313 OPTPRINT(fp,
"%s%s",comma,
"NOSELF"); comma =
",";
2315 else if (strequ(p,
"NOPROP") || strequ(p,
"NOPROPAGATE") ||
2316 strequ(p,
"NOPROPAGATE_SIGNALS")) {
2318 OPTPRINT(fp,
"%s%s",comma,
"NOPROPAGATE_SIGNALS"); comma =
",";
2320 else if (strequ(p,
"NOSIZE") || strequ(p,
"NOSIZEINFO")) {
2322 OPTPRINT(fp,
"%s%s",comma,
"NOSIZEINFO"); comma =
",";
2324 else if (strequ(p,
"CLUSTER") || strequ(p,
"CLUSTERINFO")) {
2326 OPTPRINT(fp,
"%s%s",comma,
"CLUSTERINFO"); comma =
",";
2328 else if (strequ(p,
"CALLPATH")) {
2330 OPTPRINT(fp,
"%s%s",comma,
"CALLPATH"); comma =
",";
2332 p = strtok(NULL,delim);
2335 if (*comma ==
',') {
2336 OPTPRINT(fp,
"\"\n");
2339 if (newline) OPTPRINT(fp,
"\n");
2342 env = getenv(
"DR_HOOK_CALLPATH_INDENT");
2345 if (callpath_indent < 1 || callpath_indent > 8)
callpath_indent = callpath_indent_default;
2347 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_CALLPATH_INDENT=%d\n",pfx,TIMESTR(tid),FFL,
callpath_indent);
2349 env = getenv(
"DR_HOOK_CALLPATH_DEPTH");
2354 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_CALLPATH_DEPTH=%d\n",pfx,TIMESTR(tid),FFL,
callpath_depth);
2356 env = getenv(
"DR_HOOK_CALLPATH_PACKED");
2360 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_CALLPATH_PACKED=%d\n",pfx,TIMESTR(tid),FFL,
callpath_packed);
2362 env = getenv(
"DR_HOOK_CALLTRACE");
2366 OPTPRINT(fp,
"%s %s [%s@%s:%d] DR_HOOK_CALLTRACE=%d\n",pfx,TIMESTR(tid),FFL,
opt_calltrace);
2388 while (*name && isspace(*name) && name_len > 0) {
2395 while (*from && !isspace(*from) && name_len > 0) {
2404 ABOR1(
"***Fatal error in drhook.c:trim()-function");
2417 unsigned int hash =
hashfunc(keyptr_in->name, keyptr_in->name_len);
2418 keyptr = &keydata[tid-1][hash];
2420 if (!keyptr->name) {
2421 memcpy(keyptr,keyptr_in,
sizeof(*keyptr));
2422 keyptr->next = NULL;
2426 if (!keyptr->next) {
2429 keyptr = keyptr->next;
2440 const char *filename,
int filename_len,
2441 const double *walltime,
const double *cputime,
2442 const equivalence_t *callpath,
int callpath_len,
2447 unsigned int hash, fullhash;
2454 "getkey: name='%.*s', name_len=%d, callpath_len=%d, fullhash=%u\n",
2455 name_len, name, name_len, callpath_len, fullhash);
2458 keyptr = &keydata[tid-1][hash];
2461 if (!keyptr->name) {
2463 keyptr->name_len = name_len;
2465 const char *from =
name;
2466 char *to = keyptr->name;
2468 for (; len>0; from++, len--) {
2469 *to++ = islower(*from) ?
toupper(*from) : *from;
2474 memcpy(keyptr->name, name, name_len);
2475 keyptr->name[name_len] = 0;
2477 if (filename_len > 0 &&
2481 char *p = psave =
malloc_drhook((filename_len+1)*
sizeof(*filename));
2482 memcpy(p, filename, filename_len);
2483 p[filename_len] = 0;
2485 char *s = strrchr(p,
'/');
2492 if (free_callpath) *free_callpath = 0;
2493 keyptr->callpath = callpath;
2494 keyptr->callpath_len = callpath_len;
2495 keyptr->callpath_fullhash = fullhash;
2500 (keyptr->name_len == name_len &&
2501 (!callpath || (callpath && keyptr->callpath &&
2502 keyptr->callpath_len == callpath_len &&
2503 keyptr->callpath_fullhash == fullhash)) &&
2504 ((!
opt_trim && *keyptr->name == *name && strnequ(keyptr->name, name, name_len)) ||
2505 (
opt_trim && strncasecmp(keyptr->name, name, name_len) == 0)))) {
2506 if (
opt_walltime) keyptr->wall_in = walltime ? *walltime : WALLTIME();
2507 if (
opt_cputime) keyptr->cpu_in = cputime ? *cputime : CPUTIME();
2517 if (!keyptr->next) {
2520 keyptr = keyptr->next;
2523 curkeyptr[tid-1] = keyptr;
2533 double *walltime,
double *cputime)
2535 const int sig = SIGABRT;
2536 const char sl_name[] =
"SIGABRT";
2538 if (!treeptr || !treeptr->active || treeptr->keyptr != keyptr) {
2539 char *pfx = PREFIX(tid);
2548 if (islower(*p)) *p =
toupper(*p);
2553 "%s %s [%s@%s:%d] [signal#%d(%s)]: Dr.Hook has detected an invalid" 2554 " key-pointer/handle while leaving the routine '%s' [hash=%u]\n",
2555 pfx,TIMESTR(tid),FFL,
2556 sig,sl_name,s,hash);
2561 u.keyptr = treeptr->keyptr;
2562 hash = (u.keyptr && u.keyptr->name) ?
hashfunc(u.keyptr->name,u.keyptr->name_len) : 0;
2564 "%s %s [%s@%s:%d] [signal#%d(%s)]: Expecting the key-pointer=%p" 2565 " and treeptr->active-flag = 1\n",
2566 pfx,TIMESTR(tid),FFL,
2567 sig,sl_name,u.keyptr);
2569 "%s %s [%s@%s:%d] [signal#%d(%s)]: A probable routine missing the closing" 2570 " DR_HOOK-call is '%s' [hash=%u]\n",
2571 pfx,TIMESTR(tid),FFL,
2573 (u.keyptr && u.keyptr->name) ? u.keyptr->name : NIL, hash);
2576 hash = (u.keyptr && u.keyptr->name) ?
hashfunc(u.keyptr->name,u.keyptr->name_len) : 0;
2578 "%s %s [%s@%s:%d] [signal#%d(%s)]: Got a key-pointer=%p" 2579 " and treeptr->active-flag = %d\n",
2580 pfx,TIMESTR(tid),FFL,
2581 sig,sl_name,u.keyptr,treeptr->active);
2583 "%s %s [%s@%s:%d] [signal#%d(%s)]: This key-pointer maybe associated with" 2584 " the routine '%s' [hash=%u]\n",
2585 pfx,TIMESTR(tid),FFL,
2587 (u.keyptr && u.keyptr->name) ? u.keyptr->name : NIL, hash);
2589 u.keyptr = curkeyptr[tid-1];
2590 hash = (u.keyptr && u.keyptr->name) ?
hashfunc(u.keyptr->name,u.keyptr->name_len) : 0;
2592 "%s %s [%s@%s:%d] [signal#%d(%s)]: The current key-pointer (=%p) thinks" 2593 " it maybe associated with the routine '%s' [hash=%u]\n",
2594 pfx,TIMESTR(tid),FFL,
2597 (u.keyptr && u.keyptr->name) ? u.keyptr->name : NIL, hash);
2601 "%s %s [%s@%s:%d] [signal#%d(%s)]: Aborting...\n",
2602 pfx,TIMESTR(tid),FFL,
2607 double delta_wall = 0;
2608 double delta_cpu = 0;
2612 if (keyptr->sizeinfo == 0) {
2613 keyptr->min_sizeinfo = sizeinfo;
2614 keyptr->max_sizeinfo = sizeinfo;
2617 keyptr->min_sizeinfo = MIN(keyptr->min_sizeinfo, sizeinfo);
2618 keyptr->max_sizeinfo = MAX(keyptr->max_sizeinfo, sizeinfo);
2620 keyptr->sizeinfo += sizeinfo;
2623 *cputime = CPUTIME();
2624 delta_cpu = *cputime - keyptr->cpu_in;
2627 *walltime = WALLTIME();
2628 delta_wall = *walltime - keyptr->wall_in;
2630 if (
opt_walltime) keyptr->delta_wall_all += delta_wall;
2631 if (
opt_cputime) keyptr->delta_cpu_all += delta_cpu;
2641 if (
numthreads == 0 || !keydata || !calltree || !keyself || !
overhead || !curkeyptr || !cstk) {
2662 #if defined(SV2) || defined(XD1) || defined(XT3) 2673 char *env = getenv(
"DR_HOOK_SHOW_LOCK");
2674 int konoff = env ? atoi(env) : 0;
2677 INIT_LOCKID_WITH_NAME(&
DRHOOK_lock,
"drhook.c:DRHOOK_lock");
2687 char *env = getenv(
"C_TRACEBACK");
2690 static char s[] =
"C_TRACEBACK=YES";
2706 for (j=0; j<ntids; j++) {
2716 for (j=0; j<ntids; j++) {
2721 const char *
name =
"$drhook";
2722 int name_len = strlen(name);
2724 for (j=0; j<ntids; j++) {
2727 keyptr->name_len = name_len;
2735 for (j=0; j<ntids; j++) {
2736 curkeyptr[j] = NULL;
2749 const int master = 1;
2750 const int print_option = +7;
2761 #define OVERHEAD(tid,walltime_in,cputime_in,delta,calc_delta) \ 2762 if (overhead && tid >= 1 && tid <= numthreads) { \ 2764 if (opt_walltime) delta = WALLTIME() - walltime_in; \ 2765 else if (opt_cputime) delta = CPUTIME() - cputime_in; \ 2768 overhead[tid-1] += delta; \ 2774 drhook_key_t *keyptr_self = keyself ? itself(NULL,*thread_id,0,NULL,&walltime,&cputime) : NULL; 2777 if (keyptr_self) { \ 2778 (void) itself(keyptr_self,*thread_id,1,&delta,&walltime,&cputime); \ 2779 if (opt_wallprof) u.keyptr->delta_wall_child += delta; \ 2780 else u.keyptr->delta_cpu_child += delta; \ 2781 OVERHEAD(*thread_id,walltime,cputime,delta,0); \ 2784 OVERHEAD(*thread_id,walltime,cputime,delta,1); \ 2789 int tid,
int opt,
double *delta_time,
2790 const double *walltime,
const double *cputime)
2794 keyptr = keyptr_self ? keyptr_self : keyself[tid-1];
2796 if (
opt_wallprof) keyptr->wall_in = walltime ? *walltime : WALLTIME();
2797 else keyptr->cpu_in = cputime ? *cputime : CPUTIME();
2800 else if (opt == 1) {
2803 delta = walltime ? (*walltime - keyptr->wall_in) : (WALLTIME() - keyptr->wall_in);
2804 keyptr->delta_wall_all += delta;
2807 delta = cputime ? (*cputime - keyptr->cpu_in) : (CPUTIME() - keyptr->cpu_in);
2808 keyptr->delta_cpu_all += delta;
2810 if (delta_time) *delta_time = delta;
2822 const char comma =
',';
2823 char s[DRHOOK_STRBUF];
2826 sprintf(s,
"%lld",n);
2828 ncommas = (len-1)/3;
2830 char *pd = sd + len + ncommas;
2837 if (p-s >= 0 && len%3 == 0) *pd-- = comma;
2848 const char comma =
',';
2849 char s[DRHOOK_STRBUF];
2852 sprintf(s,
"%.0f",n);
2854 ncommas = (len-1)/3;
2856 char *pd = sd + len + ncommas;
2863 if (p-s >= 0 && len%3 == 0) *pd-- = comma;
2875 const equivalence_t *callpath,
int callpath_len)
2877 if (fp && callpath && callpath_len > 0) {
2879 for (j=0; j<callpath_len; callpath++, j++) {
2880 if (callpath && callpath->keyptr && callpath->keyptr->name) {
2881 const char *
name = callpath->keyptr->name;
2882 int name_len = callpath->keyptr->name_len;
2884 if (len < 0) len = 0;
2885 fprintf(fp,
"\n%*s%.*s",len,
" ",name_len,name);
2890 "\n????callpath=%p, callpath->keyptr=%p, callpath->keyptr->name='%s'",
2891 callpath, callpath ? callpath->keyptr : 0,
2892 (callpath && callpath->keyptr && callpath->keyptr->name) ?
2893 callpath->keyptr->name : NIL);
2901 static equivalence_t *
2905 equivalence_t *callpath = NULL;
2910 treeptr = treeptr->prev;
2915 treeptr = thiscall[tid-1];
2917 callpath[j].keyptr = treeptr->keyptr;
2919 treeptr = treeptr->prev;
2923 if (callpath_len) *callpath_len = depth;
2940 const int ftnunitno = 0;
2941 const int master = 1;
2942 const int print_option = 3;
2949 const int ftnunitno = 0;
2950 const int master = 1;
2951 const int print_option = 4;
2959 const int master = 1;
2960 const int print_option = -7;
2980 if (ptr && key >
KEYNONE && n > 0) {
2983 dr_hook_prt_logical_(&ftnunitno, ptr, &nmax);
2986 dr_hook_prt_char_(&ftnunitno, ptr, &nmax);
2988 else if (key ==
KEY_I4) {
2989 dr_hook_prt_i4_(&ftnunitno, ptr, &nmax);
2991 else if (key ==
KEY_I8) {
2992 dr_hook_prt_i8_(&ftnunitno, ptr, &nmax);
2994 else if (key ==
KEY_R4) {
2995 dr_hook_prt_r4_(&ftnunitno, ptr, &nmax);
2997 else if (key ==
KEY_R8) {
2998 dr_hook_prt_r8_(&ftnunitno, ptr, &nmax);
3010 int print_traceback = 1;
3015 unsigned int crc32 = 0;
3017 const char *first_nbytes = p->ptr;
3018 int changed = memcmp(first_nbytes,p->ptr,p->watch_first_nbytes);
3021 crc32_(p->ptr, &p->nbytes, &crc32);
3022 changed = (crc32 != p->crc32);
3027 char *pfx = PREFIX(tid);
3028 if (!calc_crc)
crc32_(p->ptr, &p->nbytes, &crc32);
3030 "%s %s [%s@%s:%d] ***%s: Changed watch point '%s' at %p (%d bytes [#%d values])" 3031 " -- %s %.*s : new crc32=%u\n",
3032 pfx,TIMESTR(tid),FFL,
3033 p->abort_if_changed ?
"Error" :
"Warning",
3034 p->name, p->ptr, p->nbytes, p->nvals,
3035 label, name_len, name, crc32);
3037 if (print_traceback) {
3039 print_traceback = 0;
3041 if (allow_abort && p->abort_if_changed) {
3061 const int *allow_abort
3071 double walltime = opt_walltime ? WALLTIME() : 0; \ 3072 double cputime = opt_cputime ? CPUTIME() : 0; \ 3073 long long int hwm = opt_gethwm ? gethwm_() : 0; \ 3074 long long int stk = opt_getstk ? getstk_() : 0 3097 fprintf(stderr,
"c_drhook_getenv_(): Unable to allocate %d bytes of memory\n", slen+1);
3102 memset(value,
' ', valuelen);
3105 int len = strlen(env);
3106 if (valuelen < len) len = valuelen;
3107 memcpy(value,env,len);
3117 const int *num_threads
3124 progname =
trim(progname, &progname_len);
3125 if (progname_len > 0) {
3127 memcpy(
a_out, progname, progname_len);
3137 const char *pc = arg0;
3138 progname_len = strlen(pc);
3139 pc =
trim(pc, &progname_len);
3153 const char *array_name,
3154 const void *array_ptr,
3156 const int *abort_if_changed,
3157 const int *printkey,
3159 const int *print_traceback_when_set
3161 ,
int array_name_len)
3172 if (p->ptr == array_ptr) {
3174 free_drhook(p->name);
3184 last_watch = watch = p;
3187 last_watch->next = p;
3196 p->abort_if_changed = *abort_if_changed;
3198 p->nbytes = *nbytes;
3199 p->watch_first_nbytes = MIN(p->nbytes, MAX_WATCH_FIRST_NBYTES);
3200 memcpy(p->first_nbytes,p->ptr,p->watch_first_nbytes);
3202 crc32_(p->ptr, &p->nbytes, &p->crc32);
3203 p->printkey = *printkey;
3206 char *pfx = PREFIX(p->tid);
3208 int textlen = strlen(pfx) + strlen(p->name) + 256;
3211 "%s ***Warning: Set watch point '%s' at %p (%d bytes [%d values]) : crc32=%u",
3212 pfx, p->name, p->ptr, p->nbytes, p->nvals, p->crc32);
3214 print_watch(ftnunitno, p->printkey, p->ptr, p->nvals);
3216 if (*print_traceback_when_set)
LinuxTraceBack(pfx,TIMESTR(p->tid),NULL);
3226 const int *thread_id,
3228 const char *filename,
3231 ,
int name_len,
int filename_len)
3238 fprintf(stdout,
"<e> %d %d %.*s %lld %lld\n",
myproc,*thread_id,name_len,name,hwm,stk);
3243 int tid = *thread_id;
3244 char *pfx = PREFIX(tid);
3249 u.keyptr =
getkey(*thread_id, name, name_len,
3250 filename, filename_len,
3251 &walltime, &cputime,
3255 int free_callpath = 1;
3256 int callpath_len = 0;
3257 equivalence_t *callpath =
get_callpath(*thread_id, &callpath_len);
3258 u.keyptr =
getkey(*thread_id, name, name_len,
3259 filename, filename_len,
3260 &walltime, &cputime,
3261 callpath, callpath_len, &free_callpath);
3262 if (free_callpath) free_drhook(callpath);
3270 (void)
callstack(*thread_id, key, u.keyptr);
3276 const int ftnunitno = 0;
3277 const int print_option = 2;
3285 int tid = *thread_id;
3290 double rss = (double)(
getrss_()/1048576.0);
3295 inc_MB = tl->last_rss_MB - rss;
3297 inc_MB = tl->last_curheap_MB - curheap;
3301 if (mod == 0 || bigjump) {
3305 const int print_option = 5;
3307 tl->last_rss_MB = rss;
3308 tl->last_curheap_MB = curheap;
3321 const int *thread_id,
3323 const char *filename,
3326 ,
int name_len,
int filename_len)
3337 u.keyptr =
callstack(*thread_id, (
void *)key, NULL);
3347 fprintf(stdout,
"<x> %d %d %.*s %lld %lld\n",
myproc,*thread_id,name_len,name,hwm,stk);
3352 int tid = *thread_id;
3357 double rss = (double)(
getrss_()/1048576.0);
3362 inc_MB = tl->last_rss_MB - rss;
3364 inc_MB = tl->last_curheap_MB - curheap;
3368 if (mod == 0 || bigjump) {
3372 const int print_option = -5;
3374 tl->last_rss_MB = rss;
3375 tl->last_curheap_MB = curheap;
3383 putkey(*thread_id, u.keyptr, name, name_len,
3385 &walltime, &cputime);
3393 const long long int *
size,
3394 long long int *keyptr_addr)
3396 int tid = (thread_id && (*thread_id >= 1) && (*thread_id <=
numthreads))
3401 double size_MB = (double)((*size)/1048576.0);
3411 long long int keyptr_addr;
3414 long long int alldelta;
3416 if (curkeyptr[tid-1]) {
3418 keyptr->mem_curdelta += *
size;
3419 alldelta = keyptr->mem_curdelta + keyptr->mem_child;
3420 if (alldelta > keyptr->maxmem_alldelta) keyptr->maxmem_alldelta = alldelta;
3421 if (keyptr->mem_curdelta > keyptr->maxmem_selfdelta)
3422 keyptr->maxmem_selfdelta = keyptr->mem_curdelta;
3425 *keyptr_addr = u.keyptr_addr;
3427 keyptr->alloc_count++;
3430 if (keyptr_addr) *keyptr_addr = 0;
3440 if (keyptr_addr && (*keyptr_addr)) {
3441 u.keyptr_addr = *keyptr_addr;
3445 keyptr = curkeyptr[tid-1];
3452 long long int prev_curdelta = keyptr->mem_curdelta;
3453 keyptr->mem_curdelta += *
size;
3454 alldelta = prev_curdelta + keyptr->mem_child;
3455 if (alldelta > keyptr->maxmem_alldelta) keyptr->maxmem_alldelta = alldelta;
3456 if (*size < 0) keyptr->free_count++;
3464 double rss = (double)(
getrss_()/1048576.0);
3468 double size_MB = (double)((*size)/1048576.0);
3469 int print_option = (size_MB > 0) ? 6 : -6;
3472 tl->last_curheap_MB = curheap;
3473 tl->last_rss_MB = rss;
3482 #define PRINT_HWM() \ 3483 if (opt_gethwm) { sprintf(s,",hwm=%lldK",keyptr->hwm/1024); s += strlen(s); } 3485 #define PRINT_RSS() \ 3487 sprintf(s,",rss/max=%lldK/%lldK",keyptr->rssnow/1024, keyptr->maxrss/1024); \ 3491 #define PRINT_STK() \ 3493 sprintf(s,",stack/max=%lldK/%lldK",keyptr->stack/1024, keyptr->maxstack/1024); \ 3497 #define PRINT_PAG() \ 3499 sprintf(s,",pag=%lld",keyptr->paging); \ 3503 #define PRINT_WALL() \ 3504 if (opt_walltime) { \ 3505 double self = keyptr->delta_wall_all-keyptr->delta_wall_child; \ 3506 if (self < 0) self = 0; \ 3507 sprintf(s,",wall=%.3fs/%.3fs", \ 3508 keyptr->delta_wall_all, self); \ 3512 #define PRINT_CPU() \ 3513 if (opt_cputime) { \ 3514 double self = keyptr->delta_cpu_all-keyptr->delta_cpu_child; \ 3515 if (self < 0) self = 0; \ 3516 sprintf(s,",cpu=%.3fs/%.3fs", \ 3517 keyptr->delta_cpu_all, self); \ 3521 #define PRINT_CALLS() \ 3523 sprintf(s,",#%llu,st=%d",keyptr->calls,keyptr->status); \ 3532 return strcmp(p1->name,p2->name);
3540 return strcmp(p1->name,p2->name);
3548 if (p1->pc < p2->pc)
return 1;
3549 else if (p1->pc > p2->pc)
return -1;
3558 if (p1->pc < p2->pc)
return 1;
3559 else if (p1->pc > p2->pc)
return -1;
3566 int len = strlen(p);
3568 const char *back = &p[len-1];
3569 while (len > 0 && *back-- ==
' ') len--;
3570 while (len > 0 && *p ==
' ') { p++; len--; }
3572 if (name_len) *name_len = len;
3577 const equivalence_t * p_callpath,
int p_callpath_len,
int len,
int cluster_size)
3584 if (p_callpath && p_callpath_len > 0) {
3585 const equivalence_t * callpath = &p_callpath[p_callpath_len-1];
3587 for (j=0; j<p_callpath_len; callpath--, j++)
3588 if (callpath && callpath->keyptr && callpath->keyptr->name) {
3589 const char *name = callpath->keyptr->name;
3590 int name_len = callpath->keyptr->name_len;
3591 fprintf(fp,
"%.*s/",name_len,name);
3596 fprintf(fp,
"%.*s@%d%s%s",
3599 p_filename ?
":" :
"",
3600 p_filename ? p_filename :
"");
3603 fprintf(fp,
" [%d,%d]",
3604 p_cluster, ABS(cluster_size));
3613 #define print_routine_name(fp, p, len, cluster_size) \ 3615 print_routine_name0(fp, p->name, p->tid, p->filename, p->cluster, \ 3616 p->callpath, p->callpath_len, len, cluster_size);\ 3629 else if (ftnunitno == 6)
3633 OPTPRINT(fp,
"%s\n",line);
3640 const int *thread_id,
3641 const int *print_option,
3656 static int first_time = 0;
3657 int tid = (thread_id && (*thread_id >= 1) && (*thread_id <=
numthreads))
3660 char *pfx = PREFIX(tid);
3661 if (ftnunitno && keydata && calltree) {
3663 int abs_print_option = ABS(*print_option);
3671 if(*print_option == 2) {
3672 if(first_time == 1)
return;
3678 if (*print_option == 1) {
3686 "%s %s [%s@%s:%d] [hash#%d,nest=%d] '%s'",
3687 pfx,TIMESTR(tid),FFL,
3688 j,nestlevel,keyptr->name);
3704 keyptr = keyptr->next;
3710 else if (*print_option == 2 ||
3711 abs_print_option == 5 ||
3712 abs_print_option == 6 ||
3713 abs_print_option == 7
3717 if (*print_option == 2) {
3722 "%s %s [%s@%s:%d] %lld MB (maxheap), %lld MB (maxrss), %lld MB (maxstack)",
3723 pfx,TIMESTR(tid),FFL,
3733 if (*print_option == 2) {
3736 const int master = 1;
3746 if (abs_print_option == 7) {
3749 else if (abs_print_option == 5 || abs_print_option == 6) {
3750 treeptr = thiscall[tid-1];
3753 treeptr = calltree[tid-1];
3756 while (abs_print_option == 7 || (treeptr && treeptr->active)) {
3757 int do_print = (*print_option == 2 ||
3758 abs_print_option == 7 ||
3759 abs_print_option == 5 || abs_print_option == 6);
3761 drhook_key_t *keyptr = (abs_print_option == 7) ? NULL : treeptr->keyptr;
3763 char is_timeline = 1, kind;
3764 switch (*print_option) {
3765 case -5: kind =
'<';
break;
3766 case -6: kind =
'-';
break;
3767 case -7: kind =
'E';
break;
3768 case 5: kind =
'>';
break;
3769 case 6: kind =
'+';
break;
3770 case 7: kind =
'B';
break;
3772 case 2: kind =
':'; is_timeline = 0;
break;
3774 if (*print_option == 2 ||
3776 sprintf(s,
"%s %s [%s@%s:%d] %s%c ",
3777 pfx,TIMESTR(tid),FFL,
3778 is_timeline ?
"tl:" :
"",
3782 sprintf(s,
"%s %s [%s@%s:%d] %s%c ",
3783 pfx,TIMESTR(tid),FFL,
3784 is_timeline ?
"tl:" :
"",
3789 for (j=0; j<(*level); j++) *s++ =
' ';
3790 if (*print_option == 2) {
3792 if(strncmp(
">OMP",keyptr->name,4) == 0) {
3797 sprintf(s,
"%s ",keyptr->name);
3801 double wall = WALLTIME();
3802 double rss, curheap;
3804 if (abs_print_option == 5 || abs_print_option == 6) {
3805 curheap = tl->last_curheap_MB;
3806 rss = tl->last_rss_MB;
3809 rss = (double)(
getrss_()/1048576.0);
3812 tl->last_curheap_MB = curheap;
3813 tl->last_rss_MB = rss;
3816 sprintf(s,
"%.6f %.4g %.4g", wall, rss, curheap);
3820 "wall=%.6f cpu=%.4g hwm=%.4g rss=%.4g curheap=%.4g stack=%.4g pag=%lld",
3822 (
double)(
gethwm_()/1048576.0), rss,
3824 (
double)(
getstk_()/1048576.0),
3830 sprintf(s,
"'%s'",keyptr->name);
3833 sprintf(s,
"'#PROGRAM %s'",(*print_option == 7) ?
"BEGIN" :
"END");
3853 if (abs_print_option == 7 || abs_print_option == 5 || abs_print_option == 6)
break;
3854 if (treeptr) treeptr = treeptr->next;
3858 else if (*print_option == 3) {
3862 double tottime = 0, max_overhead_pc = 0;
3867 double flop_tot = 0, instr_tot = 0;
3868 double *flop = NULL, *instr = NULL;
3871 if (tid > 1)
return;
3892 self = keyptr->delta_wall_all - keyptr->delta_wall_child;
3895 self = keyptr->delta_cpu_all - keyptr->delta_cpu_child;
3900 flop[
t] += keyptr->avg_mflops *
self;
3901 instr[
t] += keyptr->avg_mipsrate *
self;
3905 keyptr = keyptr->next;
3911 tottime = tot[0] + ((keyself &&
opt_self > 1) ? keyself[0]->delta_wall_all : 0);
3913 double tmp = tot[
t] + ((keyself &&
opt_self > 1) ? keyself[t]->delta_wall_all : 0);
3914 tottime = MAX(tottime,tmp);
3919 for (t=0; t<numthreads; t++) tottime += (tot[t] + ((keyself && opt_self > 1) ? keyself[t]->delta_cpu_all : 0));
3922 if (tottime <= 0) tottime = 1e-10;
3932 keyptr->delta_wall_all - keyptr->delta_wall_child :
3933 keyptr->delta_cpu_all - keyptr->delta_cpu_child;
3935 keyptr->delta_wall_all :
3936 keyptr->delta_cpu_all;
3937 p->calls = keyptr->calls;
3938 p->name = keyptr->name;
3939 p->pc = (p->self/tottime) * 100.0;
3941 p->percall_ms_self = (p->self/p->calls) * 1000.0;
3942 p->percall_ms_total = (p->total/p->calls) * 1000.0;
3945 p->index = p - prof;
3948 p->mflops = keyptr->avg_mflops;
3949 p->mipsrate = keyptr->avg_mipsrate;
3953 p->filename = keyptr->filename;
3954 p->sizeinfo = keyptr->sizeinfo;
3955 p->min_sizeinfo = keyptr->min_sizeinfo;
3956 p->max_sizeinfo = keyptr->max_sizeinfo;
3957 p->sizespeed = (p->self > 0 && p->sizeinfo > 0) ? p->sizeinfo/p->self : 0;
3958 p->sizeavg = (p->calls > 0 && p->sizeinfo > 0) ? p->sizeinfo/p->calls : 0;
3959 p->callpath = keyptr->callpath;
3960 p->callpath_len = keyptr->callpath_len;
3963 keyptr = keyptr->next;
3969 double mflop_rate = 0;
3970 double mip_rate = 0;
3971 int numroutines = 0;
3975 char *prevname = NULL;
3976 const char *fmt1 =
"%5d %8.2f %12.3f %12.3f %12.3f %14llu %11.2f %11.2f %s";
3977 const char *fmt2 =
"%5d %8.2f %12.3f %12.3f %12.3f %14llu %7.0f %7.0f %7.1f %s";
3982 if (!filename)
break;
3986 "%s %s [%s@%s:%d] Writing profiling information of proc#%d into file '%s'\n",
3987 pfx,TIMESTR(tid),FFL,
3991 fp = fopen(filename,
"w");
3992 if (!fp)
goto finish_3;
4002 maxval[cluster] = p->self;
4003 p->maxval = &maxval[cluster];
4004 clusize[cluster] = 1;
4007 for (j=1; j<nprof; j++) {
4008 if (!strequ(prevname,p->name)) {
4009 (p-1)->cluster = cluster;
4010 (p-1)->maxval = &maxval[cluster];
4014 if (p->self > maxval[cluster]) maxval[cluster] = p->self;
4015 p->cluster = cluster;
4016 p->maxval = &maxval[cluster];
4021 numroutines = (nprof > 0) ? (cluster + 1) : 0;
4025 for (j=0; j<nprof; j++) {
4027 cluster = p->cluster;
4028 if (clusize[cluster] > 1) {
4029 p->is_max = (p->self == *p->maxval);
4031 clusize[cluster] = -clusize[cluster];
4035 else if (clusize[cluster] == 1) {
4042 if (tottime <= 0) tottime = 1e-10;
4046 for (j=0; j<nprof; j++) {
4047 p->pc = (p->self/tottime) * 100.0;
4059 max_overhead_pc = 0;
4061 flop_tot += flop[
t];
4062 instr_tot += instr[
t];
4064 max_overhead_pc = MAX(max_overhead_pc,
overhead[t]);
4066 fprintf(fp,
"tid#%d: overhead = %.15g s\n",t+1,
overhead[t]);
4071 fprintf(fp,
"max overhead = %.15g s, tottime = %.15g s\n",
4072 max_overhead_pc, tottime);
4074 if (tottime - max_overhead_pc > 0) {
4075 max_overhead_pc = 100.0*(max_overhead_pc/(tottime - max_overhead_pc));
4078 max_overhead_pc = 100;
4082 "Profiling information for program='%s', proc#%d:\n",
a_out,
myproc);
4083 fprintf(fp,
"\tNo. of instrumented routines called : %d\n", numroutines);
4087 fprintf(fp,
"\tInstrumentation overhead: %.2f%%\n",max_overhead_pc);
4092 long long int pag =
getpag_();
4094 "\tMemory usage : %lld MBytes (heap), %lld MBytes (rss), %lld MBytes (stack), %lld (paging)\n",
4095 hwm,rss,maxstack,pag);
4098 mflop_rate = flop_tot / tottime;
4099 mip_rate = instr_tot / tottime;
4101 "\t%s-time is %.2f sec on proc#%d, %.0f MFlops (ops#%.0f*10^6), %.0f MIPS (ops#%.0f*10^6) (%d procs, %d threads)\n",
4103 mflop_rate, flop_tot, mip_rate, instr_tot,
4108 "\t%s-time is %.2f sec on proc#%d (%d procs, %d threads)\n",
4115 "Profiling information for program='%s', proc#%d:\n",
a_out,
myproc);
4116 fprintf(stderr,
"\tNo. of instrumented routines called : %d\n", numroutines);
4117 fprintf(stderr,
"\tInstrumentation started : %s\n",start_stamp ? start_stamp :
"N/A");
4118 fprintf(stderr,
"\tInstrumentation ended : %s\n",end_stamp ? end_stamp :
"N/A");
4119 fprintf(stderr,
"\tInstrumentation overhead: %.2f%%\n",max_overhead_pc);
4122 "\t%s-time is %.2f sec on proc#%d, %.0f MFlops (ops#%.0f*10^6), %.0f MIPS (ops#%.0f*10^6) (%d procs, %d threads)\n",
4124 mflop_rate, flop_tot, mip_rate, instr_tot,
4129 "\t%s-time is %.2f sec on proc#%d (%d procs, %d threads)\n",
4135 free_drhook(end_stamp);
4138 double tmp = 100.0*(tot[
t]/tottime);
4140 mflop_rate = flop[
t]/tot[
t];
4141 mip_rate = instr[
t]/tot[
t];
4147 fprintf( fp,
"\tThread#%d: %11.2f sec (%.2f%%)",t+1,tot[t],tmp);
4148 if (
opt_hpmprof) fprintf( fp,
", %.0f MFlops (ops#%.0f*10^6), %.0f MIPS (ops#%.0f*10^6)", mflop_rate, flop[t], mip_rate, instr[t]);
4151 fprintf(stderr,
"\tThread#%d: %11.2f sec (%.2f%%)",t+1,tot[t],tmp);
4152 if (
opt_hpmprof) fprintf(stderr,
", %.0f MFlops (ops#%.0f*10^6), %.0f MIPS (ops#%.0f*10^6)", mflop_rate, flop[t], mip_rate, instr[t]);
4153 fprintf(stderr,
"\n");
4160 fprintf(fp,
" # %% Time Cumul Self Total # of calls MIPS MFlops Div-%% ");
4164 fprintf(fp,
" # %% Time Cumul Self Total # of calls Self Total ");
4166 fprintf(fp,
"Routine@<thread-id>");
4169 if (
opt_sizeinfo) fprintf(fp,
"%*s %s\n",len-20,
" ",
"(Size; Size/sec; Size/call; MinSize; MaxSize)");
4171 fprintf(fp,
" (self) (sec) (sec) (sec) \n");
4174 fprintf(fp,
" (self) (sec) (sec) (sec) ms/call ms/call\n");
4179 for (j=0; j<nprof; ) {
4180 int cluster_size = clusize[p->cluster];
4186 if (p->is_max || cluster_size == 1) cumul += p->self;
4190 ++j, p->pc, cumul, p->self, p->total, p->calls,
4191 p->mipsrate, p->mflops, p->divpc,
4192 p->is_max ?
"*" :
" ");
4196 ++j, p->pc, cumul, p->self, p->total, p->calls,
4197 p->percall_ms_self, p->percall_ms_total,
4198 p->is_max ?
"*" :
" ");
4201 print_routine_name(fp, p, len, cluster_size);
4204 char s1[DRHOOK_STRBUF], s2[DRHOOK_STRBUF], s3[DRHOOK_STRBUF];
4205 char s4[DRHOOK_STRBUF], s5[DRHOOK_STRBUF];
4211 fprintf(fp,
"\n%*s (%s; %s; %s; %s; %s)",len-20,
" ",s1,s2,s3,s4,s5);
4219 free_drhook(filename);
4220 free_drhook(maxval);
4221 free_drhook(clusize);
4231 else if (*print_option == 4) {
4237 long long int *maxseen_tot;
4238 double totmaxmem_delta;
4241 if (tid > 1)
return;
4256 self = keyptr->maxmem_selfdelta;
4257 if (
self < 0)
self = 0;
4259 maxseen_tot[
t] = MAX(maxseen_tot[t], keyptr->mem_seenmax);
4262 keyptr = keyptr->next;
4267 totmaxmem_delta = tot[0];
4269 long long int tmp = tot[
t];
4270 totmaxmem_delta = MAX(totmaxmem_delta,tmp);
4273 if (totmaxmem_delta <= 0) totmaxmem_delta = 1e-10;
4282 p->self = keyptr->maxmem_selfdelta;
4283 p->children = keyptr->mem_child;
4284 p->hwm = keyptr->mem_maxhwm;
4285 p->rss = keyptr->mem_maxrss;
4286 p->stk = keyptr->mem_maxstk;
4287 p->pag = keyptr->mem_maxpagdelta;
4288 p->leaked = keyptr->mem_curdelta;
4289 p->calls = keyptr->calls;
4290 p->alloc_count += keyptr->alloc_count;
4291 p->free_count += keyptr->free_count;
4292 p->name = keyptr->name;
4293 p->pc = (p->self/totmaxmem_delta) * 100.0;
4295 p->index = p - prof;
4296 p->filename = keyptr->filename;
4297 p->callpath = keyptr->callpath;
4298 p->callpath_len = keyptr->callpath_len;
4301 keyptr = keyptr->next;
4307 int numroutines = 0;
4309 long long int *maxval =
calloc_drhook(nprof+1,
sizeof(*maxval));
4311 char *prevname = NULL;
4312 const char *fmt1 =
"%5d %9.2f %14lld %14lld %14lld %14lld %14lld %10lld %10llu %10llu%s%10llu %s";
4313 const char *fmt = fmt1;
4317 if (!filename)
break;
4320 fprintf(stderr,
"Writing memory-profiling information of proc#%d into file '%s'\n",
myproc,filename);
4323 fp = fopen(filename,
"w");
4324 if (!fp)
goto finish_4;
4332 maxval[cluster] = p->self;
4333 p->maxval = &maxval[cluster];
4334 clusize[cluster] = 1;
4337 for (j=1; j<nprof; j++) {
4338 if (!strequ(prevname,p->name)) {
4339 (p-1)->cluster = cluster;
4340 (p-1)->maxval = &maxval[cluster];
4344 if (p->self > maxval[cluster]) maxval[cluster] = p->self;
4345 p->cluster = cluster;
4346 p->maxval = &maxval[cluster];
4351 numroutines = (nprof > 0) ? (cluster + 1) : 0;
4353 totmaxmem_delta = 0;
4355 for (j=0; j<nprof; j++) {
4357 cluster = p->cluster;
4358 if (clusize[cluster] > 1) {
4359 p->is_max = (p->self == *p->maxval);
4361 clusize[cluster] = -clusize[cluster];
4365 else if (clusize[cluster] == 1) {
4368 if (use_this) totmaxmem_delta += p->self;
4372 if (totmaxmem_delta <= 0) totmaxmem_delta = 1e-10;
4376 for (j=0; j<nprof; j++) {
4377 p->pc = (p->self/totmaxmem_delta) * 100.0;
4387 "Memory-profiling information for program='%s', proc#%d:\n",
a_out,
myproc);
4388 fprintf(fp,
"\tNo. of instrumented routines called : %d\n", numroutines);
4393 long long int hwm =
gethwm_()/1048576;
4394 long long int rss =
getrss_()/1048576;
4396 long long int pag =
getpag_();
4397 long long int maxseen = 0;
4398 long long int leaked = 0;
4400 for (j=0; j<nprof; j++) {
4401 if (p->leaked > 0) leaked += p->leaked;
4405 maxseen += maxseen_tot[
t];
4410 "\tMemory usage : %lld MBytes (max.seen), %lld MBytes (leaked), %lld MBytes (heap), %lld MBytes (max.rss), %lld MBytes (max.stack), %lld (paging)\n",
4411 maxseen,leaked,hwm,rss,maxstack,pag);
4412 fprintf(fp,
"\tNo. of procs/threads: %d procs, %d threads\n",
nproc,numthreads);
4417 "Memory-profiling information for program='%s', proc#%d:\n",
a_out,
myproc);
4418 fprintf(stderr,
"\tNo. of instrumented routines called : %d\n", numroutines);
4419 fprintf(stderr,
"\tInstrumentation started : %s\n",start_stamp ? start_stamp :
"N/A");
4420 fprintf(stderr,
"\tInstrumentation ended : %s\n",end_stamp ? end_stamp :
"N/A");
4423 free_drhook(end_stamp);
4427 fprintf(fp,
" # Memory-%% Self-alloc + Children Self-Leaked Heap Max.Stack Paging #Calls #Allocs #Frees ");
4429 fprintf(fp,
"Routine@<thread-id>");
4432 fprintf(fp,
" (self) (bytes) (bytes) (bytes) (bytes) (bytes) (delta)");
4437 for (j=0; j<nprof; ) {
4438 int cluster_size = clusize[p->cluster];
4441 if (p->children > maxseen_tot[t]) p->children = maxseen_tot[
t];
4444 p->self, p->children, p->leaked,
4445 p->hwm, p->stk, p->pag,
4446 p->calls, p->alloc_count,
4447 (p->alloc_count - p->free_count != 0) ?
"*" :
" ", p->free_count,
4448 p->is_max ?
"*" :
" ");
4450 print_routine_name(fp, p, len, cluster_size);
4458 free_drhook(filename);
4459 free_drhook(maxval);
4460 free_drhook(clusize);
4464 free_drhook(maxseen_tot);
4497 const char *filename,
int sizeinfo,
4498 int name_len,
int filename_len)
4500 static int first_time = 1;
4501 static int value = 1;
4503 extern void *cdrhookinit_(
int *value);
4504 cdrhookinit_(&value);
4507 if (value == 0)
return;
4512 filename, &sizeinfo,
4513 name_len > 0 ? name_len : strlen(name),
4514 filename_len > 0 ? filename_len : strlen(filename));
4516 else if (option == 1) {
4518 filename, &sizeinfo,
4519 name_len > 0 ? name_len : strlen(name),
4520 filename_len > 0 ? filename_len : strlen(filename));
4537 static pthread_mutex_t
hpm_lock = PTHREAD_MUTEX_INITIALIZER;
4542 #define MCYCLES (cycles * 1e-6) 4544 #define TEST_PM_ERROR(name, rc) \ 4546 fprintf(stderr,"PM_ERROR(tid#%d, pthread_self()=%d): rc=%d at %s(), line=%d, file=%s\n",\ 4547 tid,pthread_self(),rc,name,__LINE__,__FILE__); \ 4548 pm_error((char *)name, rc); \ 4556 const char *
name =
"init_hpm";
4565 #ifdef PMAPI_POST_P4 4570 pm_groups_info_t pmgroupsinfo;
4575 #ifdef PMAPI_POST_P4 4576 rc = pm_initialize(PM_VERIFIED | PM_UNVERIFIED | PM_CAVEAT | PM_GET_GROUPS,
4577 &pminfo, &pmgroupsinfo, PM_CURRENT);
4579 rc = pm_init(PM_VERIFIED | PM_UNVERIFIED | PM_CAVEAT | PM_GET_GROUPS,
4580 &pminfo, &pmgroupsinfo);
4582 TEST_PM_ERROR((
char *)name, rc);
4584 if (
myproc <= 1) fprintf(stderr,
4585 ">>>pm_init() for ECMWF/OpenMP-tid#%d, pthread_self()=%d\n",
4586 tid,pthread_self());
4590 #if defined(PMAPI_P7) 4591 char *env = getenv(
"HPM_GROUP");
4594 fprintf(stderr,
"hpm_group = %d\n",
hpm_grp);
4595 if (
hpm_grp == 150) group = 150;
4596 if (
hpm_grp == 141) group = 141;
4621 #elif defined(PMAPI_P6) 4622 const int group = 186;
4635 #elif defined(PMAPI_P5_PLUS) 4637 const int group = 150;
4651 const int group = 60;
4666 if (
myproc <= 1) fprintf(stderr,
"group = %d\n",group);
4675 for (i=0; i<MAX_COUNTERS; i++) {
4676 pmprog.events[
i] = COUNT_NOTHING;
4678 pmprog.events[0] = group;
4684 pmprog.mode.b.user = 1;
4685 pmprog.mode.b.process = 0;
4691 pmprog.mode.b.is_group = 1;
4697 pmprog.mode.b.count = 0;
4704 rc = pm_set_program_mythread(&pmprog);
4705 TEST_PM_ERROR((
char *)name, rc);
4707 rc = pm_start_mythread();
4708 TEST_PM_ERROR((
char *)name, rc);
4715 const char *
name =
"stop_only_hpm";
4728 if (pstop && !pstop->counter_stopped) {
4729 rc = pm_get_data_mythread(&pmdata);
4730 TEST_PM_ERROR((
char *)name, rc);
4732 if (pstop && pstop->counter_in && !pstop->counter_stopped) {
4733 for (i=0; i<MAX_COUNTERS; i++) {
4734 pstop->counter_sum[
i] += (pmdata.accu[
i] - pstop->counter_in[
i]);
4736 pstop->counter_stopped = 1;
4751 const char *
name =
"stopstart_hpm";
4764 rc = pm_get_data_mythread(&pmdata);
4765 TEST_PM_ERROR((
char *)name, rc);
4767 if (pstop && pstop->counter_in && !pstop->counter_stopped) {
4768 for (i=0; i<MAX_COUNTERS; i++) {
4769 pstop->counter_sum[
i] += (pmdata.accu[
i] - pstop->counter_in[
i]);
4771 pstop->counter_stopped = 1;
4775 if (!pstart->counter_in ) pstart->counter_in =
calloc_drhook(MAX_COUNTERS,
sizeof(*pstart->counter_in ));
4776 if (!pstart->counter_sum) pstart->counter_sum =
calloc_drhook(MAX_COUNTERS,
sizeof(*pstart->counter_sum));
4777 for (i=0; i<MAX_COUNTERS; i++) {
4778 pstart->counter_in[
i] = pmdata.accu[
i];
4780 pstart->counter_stopped = 0;
4796 static double cycles = 0;
4798 #define MCYCLES (cycles * 1e-6) 4800 #define TEST_PM_ERROR(name, rc) \ 4802 fprintf(stderr,"PM_ERROR(tid#%d, pthread_self()=%d): rc=%d at %s(), line=%d, file=%s\n",\ 4803 tid,pthread_self(),rc,name,__LINE__,__FILE__); \ 4804 pm_error((char *)name, rc); \ 4812 const char *
name =
"init_hpm";
4821 const char *
name =
"stop_only_hpm";
4826 if (pstop && !pstop->counter_stopped) {
4828 if (pstop && pstop->counter_in && !pstop->counter_stopped) {
4829 #if defined(DT_FLOP) 4830 pstop->counter_sum[0] += ((
long long int)
flop_() - pstop->counter_in[0]);
4832 pstop->counter_sum[ENTRY_4] += (_rtc() - pstop->counter_in[ENTRY_4]);
4834 pstop->counter_sum[ENTRY_4] += (
irtc_() - pstop->counter_in[ENTRY_4]);
4837 pstop->counter_stopped = 1;
4846 const char *
name =
"stopstart_hpm";
4851 if (pstop && pstop->counter_in && !pstop->counter_stopped) {
4852 #if defined(DT_FLOP) 4853 pstop->counter_sum[0] += ((
long long int)
flop_() - pstop->counter_in[0]);
4855 pstop->counter_sum[ENTRY_4] += (_rtc() - pstop->counter_in[ENTRY_4]);
4857 pstop->counter_sum[ENTRY_4] += (
irtc_() - pstop->counter_in[ENTRY_4]);
4860 pstop->counter_stopped = 1;
4864 if (!pstart->counter_in ) pstart->counter_in =
calloc_drhook(MAX_COUNTERS,
sizeof(*pstart->counter_in ));
4865 if (!pstart->counter_sum) pstart->counter_sum =
calloc_drhook(MAX_COUNTERS,
sizeof(*pstart->counter_sum));
4866 #if defined(DT_FLOP) 4867 pstart->counter_in[0] = (
long long int)
flop_();
4869 pstart->counter_in[ENTRY_4] = _rtc();
4871 pstart->counter_in[ENTRY_4] =
irtc_();
4874 pstart->counter_stopped = 0;
4884 if (keyptr && keyptr->counter_sum && keyptr->counter_sum[ENTRY_4] > 0) {
4885 long long int sum = 0;
4886 #if defined(DT_FLOP) 4887 sum = keyptr->counter_sum[0];
4888 #elif defined(PMAPI_P7) 4891 sum = 2 * keyptr->counter_sum[2] + keyptr->counter_sum[3];
4894 sum = 2 * keyptr->counter_sum[0] + 4 * keyptr->counter_sum[1] + 2 * keyptr->counter_sum[3];
4896 #elif defined(PMAPI_P6) 4898 sum = keyptr->counter_sum[0] + 2 * keyptr->counter_sum[1];
4899 #elif defined(PMAPI_P5_PLUS) 4901 sum = 2 * keyptr->counter_sum[1] + keyptr->counter_sum[3];
4903 sum = keyptr->counter_sum[1] + keyptr->counter_sum[2] + keyptr->counter_sum[3] - keyptr->counter_sum[5];
4906 mflops = (sum * MCYCLES)/keyptr->counter_sum[ENTRY_4];
4914 double mipsrate = 0;
4915 #if defined(DT_FLOP) 4918 if (keyptr && keyptr->counter_sum && keyptr->counter_sum[ENTRY_4] > 0) {
4919 mipsrate = (keyptr->counter_sum[ENTRY_6] * MCYCLES)/keyptr->counter_sum[ENTRY_4];
4929 #if defined(DT_FLOP) 4932 if (keyptr && keyptr->counter_sum) {
4933 long long int sum = 0;
4934 #if defined(PMAPI_P7) 4937 sum = 2 * keyptr->counter_sum[2] + keyptr->counter_sum[3];
4938 if (sum > 0) divpc = (keyptr->counter_sum[0]*100.0)/
sum;
4941 sum = 2 * keyptr->counter_sum[0] + 4 * keyptr->counter_sum[1] + 2 * keyptr->counter_sum[3];
4942 if (sum > 0) divpc = (keyptr->counter_sum[1]*100.0)/
sum;
4944 #elif defined(PMAPI_P6) 4946 sum = keyptr->counter_sum[0] + 2 * keyptr->counter_sum[1];
4947 if (sum > 0) divpc = (keyptr->counter_sum[2]*100.0)/
sum;
4948 #elif defined(PMAPI_P5_PLUS) 4950 sum = 2 * keyptr->counter_sum[1] + keyptr->counter_sum[3];
4951 if (sum > 0) divpc = (keyptr->counter_sum[0]*100.0)/
sum;
4953 sum = keyptr->counter_sum[1] + keyptr->counter_sum[2] + keyptr->counter_sum[3] - keyptr->counter_sum[5];
4954 if (sum > 0) divpc = (keyptr->counter_sum[0]*100.0)/
sum;
4965 if (keyptr && keyptr->counter_sum && keyptr->counter_sum[ENTRY_4] > 0) {
4966 #if defined(DT_FLOP) 4967 sum = (keyptr->counter_sum[0]) * 1e-6;
4968 #elif defined(PMAPI_P7) 4971 sum = (2 * keyptr->counter_sum[2] + keyptr->counter_sum[3]) * 1e-6;
4974 sum = (2 * keyptr->counter_sum[0] + 4 * keyptr->counter_sum[1] + 2 * keyptr->counter_sum[3]) * 1e-6;
4976 #elif defined(PMAPI_P6) 4978 sum = (keyptr->counter_sum[0] + 2 * keyptr->counter_sum[1]) * 1e-6;
4979 #elif defined(PMAPI_P5_PLUS) 4981 sum = (2 * keyptr->counter_sum[1] + keyptr->counter_sum[3]) * 1e-6;
4983 sum = (keyptr->counter_sum[1] + keyptr->counter_sum[2] + keyptr->counter_sum[3] - keyptr->counter_sum[5]) * 1e-6;
4985 if (sum < 0) sum = 0;
4994 #if defined(DT_FLOP) 4997 if (keyptr && keyptr->counter_sum && keyptr->counter_sum[ENTRY_4] > 0) {
4998 sum = keyptr->counter_sum[ENTRY_6] * 1e-6;
5019 #define FORTRAN_CALL 5021 #if defined(CRAY) && !defined(SV2) 5022 #define util_cputime_ UTIL_CPUTIME 5023 #define util_walltime_ UTIL_WALLTIME 5029 #include <sys/types.h> 5030 #include <sys/times.h> 5033 #include <sys/param.h> 5035 #include <sys/time.h> 5042 static double time_init = -1;
5043 double time_in_secs;
5044 #if !defined(CRAYXT) 5045 struct timeval tbuf;
5046 if (gettimeofday(&tbuf,NULL) == -1) perror(
"UTIL_WALLTIME");
5048 if (time_init == -1) time_init =
5049 (double) tbuf.tv_sec + (tbuf.tv_usec / 1000000.0);
5052 (double) tbuf.tv_sec + (tbuf.tv_usec / 1000000.0) - time_init;
5054 if (time_init == -1) time_init = dclock();
5055 time_in_secs = dclock() - time_init;
5057 return time_in_secs;
5071 extern clock_t
times (
struct tms *buffer);
5077 static int first_time = 1;
5078 static double clock_ticks = 0;
5080 (void)
times(&tbuf);
5083 clock_ticks = (double) sysconf(_SC_CLK_TCK);
5087 return (tbuf.tms_utime + tbuf.tms_stime +
5088 tbuf.tms_cutime + tbuf.tms_cstime) / clock_ticks;
5097 double w, time_in_secs;
5098 static double wallref = 0;
5099 extern FORTRAN_CALL gettod_(
double *);
5100 if (wallref == 0) gettod_(&wallref);
5102 time_in_secs = (w - wallref) * 0.000001;
5103 return time_in_secs;
5109 #include <sys/types.h> 5110 #include <sys/param.h> 5111 #include <sys/signal.h> 5112 #include <sys/fault.h> 5113 #include <sys/syscall.h> 5114 #include <sys/procfs.h> 5115 #include <sys/proc.h> 5122 if (rusage) rusage->ru_maxrss = 0;
5124 if (who == RUSAGE_SELF && rusage) {
5125 static int maxrss = 0;
5126 static int oldpid = -1;
5127 static char procfile[20] =
"";
5128 static char *pf = NULL;
5132 static int fildes = -1;
5135 if (oldpid != pid) {
5142 sprintf(procfile,
"/proc/%d",pid);
5144 fildes = open(procfile, O_RDONLY);
5147 if (fildes == -1)
return rc;
5156 if (ioctl(fildes, PIOCGETPR, &proc) == -1) {
5157 perror(
"ioctl@fujitsu_getrusage(PIOCGETPR)");
5161 size = proc.p_brksize + proc.p_stksize;
5162 if (size > maxrss) maxrss =
size;
5163 rusage->ru_maxrss = maxrss;
5177 #if defined(SGI) || defined(VPP) 5179 struct rusage rusage;
5182 getrusage(0, &rusage);
5189 int pagesize = getpagesize();
5190 getrusage(0, &rusage);
5193 int pagesize = getpagesize();
5194 getrusage(0, &rusage);
5197 int pagesize = getpagesize();
5198 getrusage(0, &rusage);
5200 ret_value = (rusage.ru_maxrss * pagesize + 7) / 8;
5209 #define SECS(x) ((int)(x)) 5210 #define NSECS(x) ((int)(1000000000 * ((x) - SECS(x)))) 5215 const char delim[] =
", \t/";
5217 p = strtok(s,delim);
5219 int target_myproc, target_omptid, target_sig;
5221 int nelems = sscanf(p,
"%d:%d:%d:%lf",
5222 &target_myproc, &target_omptid, &target_sig, &start_time);
5225 ntids = omp_get_max_threads();
5228 (target_myproc ==
myproc || target_myproc == -1) &&
5229 (target_omptid == -1 || (target_omptid >= 1 && target_omptid <= ntids)) &&
5230 (target_sig >= 1 && target_sig <= NSIG) &&
5232 #pragma omp parallel num_threads(ntids) 5235 if (target_omptid == -1 || target_omptid == tid) {
5236 char *pfx = PREFIX(tid);
5237 timer_t timerid = { 0 };
5238 struct itimerspec its = { 0 } ;
5239 struct sigevent sev = { 0 } ;
5240 sev.sigev_notify = SIGEV_THREAD_ID | SIGEV_SIGNAL;
5241 sev.sigev_signo = target_sig;
5243 sev._sigev_un._tid =
gettid();
5244 sev.sigev_value.sival_ptr = &timerid;
5246 its.it_value.tv_sec = SECS(start_time);
5247 its.it_value.tv_nsec = NSECS(start_time);
5249 its.it_interval.tv_sec = 0;
5250 its.it_interval.tv_nsec = 0;
5252 timer_create(CLOCK_MONOTONIC, &sev, &timerid);
5254 timer_settime(timerid, 0, &its, NULL);
5256 #pragma omp critical (TimedKill) 5259 "%s %s [%s@%s:%d] Developer timer (%s) expires" 5260 " after %.3fs through signal#%d (ntids=%d)\n",
5261 pfx,TIMESTR(tid),FFL,
5263 start_time, target_sig, ntids);
5269 p = strtok(NULL,delim);
static int callpath_depth
void dr_hook_prt_(const int *ftnunitno, const char *s, int s_len)
const char * ec_GetArgs(int argno)
static int set_default_handler(int sig, int unlimited_corefile, int verbose)
void c_drhook_print_(const int *ftnunitno, const int *thread_id, const int *print_option, int *level)
static volatile sig_atomic_t signal_handler_called
static const char * trim(const char *name, int *n)
void c_drhook_getenv_(const char *s, char *value, int slen, const int valuelen)
static drhook_timeline_t * timeline
static int drhook_trapfpe
static void dump_file(const char *pfx, int tid, int sig, int nsigs, const char filename[])
static drhook_key_t * itself(drhook_key_t *keyptr_self, int tid, int opt, double *delta_time, const double *walltime, const double *cputime)
static int set_unlimited_corefile(unsigned long long int *hardlimit)
struct drhook_prefix_t drhook_prefix_t
static void process_options()
static volatile sig_atomic_t opt_gencore
struct drhook_key_t drhook_key_t
static char * TimeStr(char *s, int slen)
char pad[CACHELINESIZE - 2 *WORDLEN]
struct callstack_t callstack_t
static int prof_pc_comp_desc(const void *v1, const void *v2)
static drhook_key_t * insertkey(int tid, const drhook_key_t *keyptr_in)
static void putkey(int tid, drhook_key_t *keyptr, const char *name, int name_len, int sizeinfo, double *walltime, double *cputime)
static void trapfpe(void)
void c_drhook_check_watch_(const char *where, const int *allow_abort, int where_len)
static int opt_propagate_signals
static void signal_harakiri(int sig SIG_EXTRA_ARGS)
static drhook_calltree_t ** thiscall
static void print_routine_name0(FILE *fp, const char *p_name, int p_tid, const char *p_filename, int p_cluster, const equivalence_t *p_callpath, int p_callpath_len, int len, int cluster_size)
static int drhook_dump_hugepages
static void catch_signals(int silent)
static double dclock_start
static double mflops_hpm(const drhook_key_t *keyptr)
static int callpath_indent
struct drhook_timeline_t drhook_timeline_t
unsigned int callpath_hashfunc(unsigned int inithash, const equivalence_t *callpath, int callpath_len, unsigned int *fullhash)
static volatile unsigned long long int saved_corefile_hardlimit
long long int getmaxrss_()
static int spin(int secs)
static void restore_default_signals(int silent)
static drhook_sig_t siglist[1+NSIG]
static int opt_gencore_signal
static volatile sig_atomic_t signal_handler_ignore_atexit
static char * strdup2_drhook(const char *s, int s_len)
static void signal_drhook_init(int enforce)
static char * get_mon_out(int me)
static void set_timed_kill()
quick &counting sorts only inumt inumt name
struct drhook_sig_t drhook_sig_t
long long int getmaxcurheap_()
static double mips_hpm(const drhook_key_t *keyptr)
FORTRAN_CALL int util_ihpstat_(int *option)
clock_t times(struct tms *buffer)
static drhook_watch_t * watch
static void stopstart_hpm(int tid, drhook_key_t *pstop, drhook_key_t *pstart)
static int opt_random_memstat
void necsx_trbk_(const char *msg, int msglen)
static drhook_key_t * callstack(int tid, void *key, drhook_key_t *keyptr)
static char * start_stamp
struct drhook_watch_t drhook_watch_t
static unsigned int hashmask
static void * calloc_drhook(size_t nmemb, size_t size)
long long int irtc_rate_()
static void signal_gencore(int sig SIG_EXTRA_ARGS)
static o_lock_t DRHOOK_lock
static int drhook_harakiri_timeout
static int opt_clusterinfo
static drhook_prefix_t * ec_drhook
static drhook_key_t * getkey(int tid, const char *name, int name_len, const char *filename, int filename_len, const double *walltime, const double *cputime, const equivalence_t *callpath, int callpath_len, int *free_callpath)
static pthread_mutex_t hpm_lock
static double opt_hpmstop_mflops
static unsigned int hashsize
void c_drhook_watch_(const int *onoff, const char *array_name, const void *array_ptr, const int *nbytes, const int *abort_if_changed, const int *printkey, const int *nvals, const int *print_traceback_when_set, int array_name_len)
static int fujitsu_getrusage(int who, struct rusage *rusage)
static void trapfpe_treatment(int sig, int silent)
static long long int opt_timeline_freq
integer, dimension(180), parameter nmax
static void random_memstat(int tid, int enforce)
static drhook_key_t ** curkeyptr
static void insert_calltree(int tid, drhook_key_t *keyptr)
void c_drhook_raise_(const int *sig)
void c_drhook_init_signals_(const int *enforce)
static int drhook_dump_smaps
static void ignore_signals(int silent)
long long int getmaxstk_()
static void lld_commie(long long int n, char sd[])
static long long int irtc_start
static double percent_limit
static volatile sig_atomic_t unlimited_corefile_retcode
static void DrHookPrint(int ftnunitno, const char *line)
static long long int opt_hpmstop_threshold
static int memprof_pc_comp_desc(const void *v1, const void *v2)
static double my_inv_irtc_rate
void crc32_(const void *vbuf, const int *pnbuf, unsigned int *pnCRC)
static void * malloc_drhook(size_t size)
static void dump_hugepages(int enforce, const char *pfx, int tid, int sig, int nsigs)
static void remove_calltree(int tid, drhook_key_t *keyptr, const double *delta_wall, const double *delta_cpu)
struct drhook_prof_t drhook_prof_t
static int callpath_packed
void coml_set_lockid_(o_lock_t *mylock)
unsigned int hashfunc(const char *s, int s_len)
static void untrapfpe(void)
static int opt_timeline_thread
static double my_irtc_rate
static int opt_timeline_format
static void print_watch(int ftnunitno, int key, const void *ptr, int n)
static void dbl_commie(double n, char sd[])
static char * timestamp()
void dr_hook_procinfo_(int *myproc, int *nproc)
static void memstat(drhook_key_t *keyptr, const int *thread_id, int in_getkey)
static equivalence_t * get_callpath(int tid, int *callpath_len)
static void init_drhook(int ntids)
static double opt_timeline_MB
void LinuxTraceBack(const char *prefix, const char *timestr, void *sigcontextptr)
intent(out) overrides sub arrays one Sort by the least significant key first sum(iindex(1:n))
static drhook_key_t ** keyself
static char * safe_llitoa(long long int i, char b[], int blen)
static int atp_ignore_sigterm
static char * get_memmon_out(int me)
int snprintf(char *str, size_t size, const char *format,...)
static int drhook_dump_buddyinfo
void c_drhook_init_(const char *progname, const int *num_threads, int progname_len)
static int * hpm_tid_init
static char * strdup_drhook(const char *s)
static double mflop_count(const drhook_key_t *keyptr)
static void gdb__sigdump(int sig SIG_EXTRA_ARGS)
void Dr_Hook(const char *name, int option, double *handle, const char *filename, int sizeinfo, int name_len, int filename_len)
static void init_hpm(int tid)
static int atp_max_analysis_time
static drhook_calltree_t ** calltree
long long int getcurheap_thread_(const int *tidnum)
void c_drhook_end_(const char *name, const int *thread_id, const double *key, const char *filename, const int *sizeinfo, int name_len, int filename_len)
long long int getmaxhwm_()
static int prof_name_comp(const void *v1, const void *v2)
struct drhook_memprof_t drhook_memprof_t
static double divpc_hpm(const drhook_key_t *keyptr)
long long int getmaxcurheap_thread_(const int *tidnum)
static void unroll_callpath(FILE *fp, int len, const equivalence_t *callpath, int callpath_len)
void c_drhook_start_(const char *name, const int *thread_id, double *key, const char *filename, const int *sizeinfo, int name_len, int filename_len)
void c_drhook_set_lhook_(const int *lhook)
long long int getcurheap_()
static callstack_t ** cstk
static void stop_only_hpm(int tid, drhook_key_t *pstop)
static int memprof_name_comp(const void *v1, const void *v2)
static double drhook_dump_hugepages_freq
void coml_set_debug_(const int *konoff, int *kret)
static int opt_timeline_unitno
static double mip_count(const drhook_key_t *keyptr)
static void flptrap(int sig)
static const char * trim_and_adjust_left(const char *p, int *name_len)
struct drhook_calltree_t drhook_calltree_t
static char * drhook_timed_kill
static int allow_coredump
static void signal_drhook(int sig SIG_EXTRA_ARGS)
static void check_watch(const char *label, const char *name, int name_len, int allow_abort)
subroutine t(CDPREF, CDSUFF, KCODPA, LDNIVA, PMULTI)
static drhook_watch_t * last_watch
void coml_unset_lockid_(o_lock_t *mylock)
void c_drhook_memcounter_(const int *thread_id, const long long int *size, long long int *keyptr_addr)
void coml_test_lockid_(int *is_set, o_lock_t *mylock)
static drhook_key_t ** keydata
void c_drhook_process_options_(const int *lhook, const int *Myproc, const int *Nproc)