chpl_bool chpl_mem_descTrack(chpl_mem_descInt_t mdi) { // // For the runtime-defined descriptor types, for now we either track // the ones the static definition in the table says to, or we track // them all. In the future we can imagine wanting to be able to // turn them on and off individually, but we can wait for a use case // before designing that capability. // if (mdi < CHPL_RT_MD_NUM) { static chpl_bool track_all_mds; static volatile chpl_bool track_all_mds_set = false; // // Init is parallel-safe because all stores are of the same values. // if (!track_all_mds_set) { track_all_mds = chpl_get_rt_env_bool("MEMTRACK_ALL_MDS", false); track_all_mds_set = true; } return track_all_mds || rt_md[mdi].track; } return true; }
static void chpl_stack_unwind(void){ // This is just a prototype using libunwind unw_cursor_t cursor; unw_context_t uc; unw_word_t wordValue; char buffer[128]; unsigned int line; #ifdef __linux__ unw_proc_info_t info; // Get the exec path and name for the precise line printing char process_name[128]; line = readlink("/proc/self/exe", process_name, sizeof(process_name)); // It unlikely to happen but this means that the process name is too big // for our buffer. In this case, we truncate the name if(line == sizeof(process_name)) line = sizeof(process_name)-1; process_name[line] = '\0'; #endif // Check if we need to print the stack trace (default = yes) if(! chpl_get_rt_env_bool("UNWIND", true)) { return; } line = 0; unw_getcontext(&uc); unw_init_local(&cursor, &uc); if(chpl_sizeSymTable > 0) fprintf(stderr,"Stacktrace\n\n"); // This loop does the effective stack unwind, see libunwind documentation while (unw_step(&cursor) > 0) { unw_get_proc_name(&cursor, buffer, sizeof(buffer), &wordValue); // Since this stack trace is printed out a program exit, we do not believe // it is performance sensitive. Additionally, this initial implementation // favors simplicity over performance. // // If it becomes necessary to improve performance, this code could use be // faster using one of these two strategies: // 1) Use a hashtable or map to find entries in chpl_funSymTable, or // 2) Emit chpl_funSymTable in sorted order and use binary search on it for(int t = 0; t < chpl_sizeSymTable; t+=2 ){ if (!strcmp(chpl_funSymTable[t], buffer)){ #ifdef __linux__ // Maybe we can get a more precise line number unw_get_proc_info(&cursor, &info); line = chpl_unwind_getLineNum(process_name, (void *)(info.start_ip + wordValue)); // We wasn't able to obtain the line number, let's use the procedure // line number if(line == 0) line = chpl_filenumSymTable[t+1]; #else line = chpl_filenumSymTable[t+1]; #endif fprintf(stderr,"%s() at %s:%d\n", chpl_funSymTable[t+1], chpl_lookupFilename(chpl_filenumSymTable[t]), line); break; } } } }