Пример #1
0
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;
}
Пример #2
0
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;
      }
    }
  }
}