Ejemplo n.º 1
0
void 
hpcrun_unw_init_cursor(hpcrun_unw_cursor_t* cursor, void* context)
{
  mcontext_t *mc = GET_MCONTEXT(context);

  cursor->pc_unnorm = MCONTEXT_PC(mc); 
  cursor->bp 	    = MCONTEXT_BP(mc);
  cursor->sp 	    = MCONTEXT_SP(mc);
  cursor->ra_loc    = NULL;

  TMSG(UNW, "unw_init: pc=%p, ra_loc=%p, sp=%p, bp=%p", 
       cursor->pc_unnorm, cursor->ra_loc, cursor->sp, cursor->bp);

  cursor->flags = 0; // trolling_used
  cursor->intvl = hpcrun_addr_to_interval(cursor->pc_unnorm,
					  cursor->pc_unnorm, &cursor->pc_norm);
  if (!cursor->intvl) {
    EMSG("unw_init: cursor could NOT build an interval for initial pc = %p",
	 cursor->pc_unnorm);
    cursor->pc_norm = hpcrun_normalize_ip(cursor->pc_unnorm, NULL);
  }

  if (MYDBG) { dump_ui((unwind_interval *)cursor->intvl, 0); }
}
Ejemplo n.º 2
0
void run(char * filename, unsigned long nmaxvalues, double min, double max) {
    unsigned int i;
    unsigned int nvalues;
    double empty_space_needed;
    unsigned int left;
    unsigned int right;
    double median = 0, leftquartile = 0, rightquartile = 0, percentage = 0;
    gsl_vector * values = gsl_vector_alloc(nmaxvalues);
    gsl_vector * medians = gsl_vector_alloc(100);
    gsl_vector * leftquartiles = gsl_vector_alloc(100);
    gsl_vector * rightquartiles = gsl_vector_alloc(100);
    gsl_vector * percentages = gsl_vector_alloc(100);
    gsl_vector * vectors[4];
    unsigned int npeaks = 0;
    vectors[0] = percentages;
    vectors[1] = medians;
    vectors[2] = leftquartiles;
    vectors[3] = rightquartiles;

    dump_ul("nmaxvalues", nmaxvalues);
    nvalues = fill_vector(values, filename, min, max);
    dump_ul("nvalues", nmaxvalues);
    debug("data ready!");
    qsort(values->data, nvalues, sizeof(double), double_comp);
    debug("data sorted!");

    /* 0.1% of parameter space */
    empty_space_needed = (max - min) / 100;
    dump_d("empty_space_needed", empty_space_needed);
    dump_d("min", min);
    dump_d("max", max);

    assert(gsl_vector_get(values, 0) >= min);
    assert(gsl_vector_get(values, 0) <= max);
    assert(gsl_vector_get(values, nvalues - 1) >= min);
    assert(gsl_vector_get(values, nvalues - 1) <= max);

    left = 0;
    while (1) {
        dump_ui("found left side", left);
        dump_d("left side", gsl_vector_get(values, left));
        right = left + 1;
        for (; right < nvalues; right++) {
            if (gsl_vector_get(values, right) - gsl_vector_get(values, right
                    - 1) > empty_space_needed) {
                dump_d("gap till next", gsl_vector_get(values, right) - gsl_vector_get(values, right
                        - 1));
                break;
            }
        }
        right--;
        dump_ui("found right side", right);
        dump_d("right side", gsl_vector_get(values, right));
        analyse_part(values, left, right, nvalues, &median, &leftquartile,
                     &rightquartile, &percentage);
        gsl_vector_set(medians, npeaks, median);
        gsl_vector_set(leftquartiles, npeaks, leftquartile);
        gsl_vector_set(rightquartiles, npeaks, rightquartile);
        gsl_vector_set(percentages, npeaks, percentage);
        npeaks++;
        assert(npeaks < 100);

        if (right == nvalues - 1)
            break;
        left = right + 1;
    }

#ifndef NOSORT
    sort(vectors, 4, npeaks);
#endif
    printf("median\t-\t+\tpercent\n");
    fflush(NULL);
    for (i = 0; i < npeaks; i++) {
        printf("%f\t%f\t%f\t%f\n", gsl_vector_get(medians, i), gsl_vector_get(
                   medians, i) - gsl_vector_get(leftquartiles, i), gsl_vector_get(
                   rightquartiles, i) - gsl_vector_get(medians, i),
               gsl_vector_get(percentages, i));
    }

    gsl_vector_free(values);
    gsl_vector_free(medians);
    gsl_vector_free(leftquartiles);
    gsl_vector_free(rightquartiles);
    gsl_vector_free(percentages);
}
Ejemplo n.º 3
0
static step_state
unw_step_bp(hpcrun_unw_cursor_t* cursor)
{
  void *sp, **bp, *pc; 
  void **next_sp, **next_bp, *next_pc;

  unwind_interval *uw;

  TMSG(UNW_STRATEGY,"Using BP step");
  // current frame
  bp = cursor->bp;
  sp = cursor->sp;
  pc = cursor->pc_unnorm;
  uw = (unwind_interval *)cursor->intvl;

  TMSG(UNW,"step_bp: cursor { bp=%p, sp=%p, pc=%p }", bp, sp, pc);
  if (MYDBG) { dump_ui(uw, 0); }

  if (!(sp <= (void*) bp)) {
    TMSG(UNW,"  step_bp: STEP_ERROR, unwind attempted, but incoming bp(%p) was not"
	 " >= sp(%p)", bp, sp);
    return STEP_ERROR;
  }
  if (DISABLED(OMP_SKIP_MSB)) {
    if (!((void *)bp < monitor_stack_bottom())) {
      TMSG(UNW,"  step_bp: STEP_ERROR, unwind attempted, but incoming bp(%p) was not"
	   " between sp (%p) and monitor stack bottom (%p)", 
	   bp, sp, monitor_stack_bottom());
      return STEP_ERROR;
    }
  }
  // bp relative
  next_sp  = (void **)((void *)bp + uw->bp_bp_pos);
  next_bp  = *next_sp;
  next_sp  = (void **)((void *)bp + uw->bp_ra_pos);
  void* ra_loc = (void*) next_sp;
  next_pc  = *next_sp;
  next_sp += 1;
  if ((void *)next_sp > sp) {
    // this condition is a weak correctness check. only
    // try building an interval for the return address again if it succeeds
    ip_normalized_t next_pc_norm = ip_normalized_NULL;
    uw = (unwind_interval *)hpcrun_addr_to_interval(((char *)next_pc) - 1, 
						    next_pc, &next_pc_norm);
    if (! uw){
      if (((void *)next_sp) >= monitor_stack_bottom()) {
        TMSG(UNW,"  step_bp: STEP_STOP_WEAK, next_sp >= monitor_stack_bottom,"
	     " next_sp = %p", next_sp);
        return STEP_STOP_WEAK;
      }
      TMSG(UNW,"  step_bp: STEP_ERROR, cannot build interval for next_pc(%p)", next_pc);
      return STEP_ERROR;
    }
    else {
      cursor->pc_unnorm = next_pc;
      cursor->bp        = next_bp;
      cursor->sp        = next_sp;
      cursor->ra_loc    = ra_loc;
      cursor->pc_norm   = next_pc_norm;
      
      cursor->intvl = (splay_interval_t *)uw;
      TMSG(UNW,"  step_bp: STEP_OK, has_intvl=%d, bp=%p, sp=%p, pc=%p",
	   cursor->intvl != NULL, next_bp, next_sp, next_pc);
      return STEP_OK;
    }
  }
  else {
    TMSG(UNW_STRATEGY,"BP unwind fails: bp (%p) < sp (%p)", bp, sp);
    return STEP_ERROR;
  }
  EMSG("FALL Through BP unwind: shouldn't happen");
  return STEP_ERROR;
}
Ejemplo n.º 4
0
static step_state
unw_step_sp(hpcrun_unw_cursor_t* cursor)
{
  TMSG(UNW_STRATEGY,"Using SP step");

  // void *stack_bottom = monitor_stack_bottom();

  // current frame
  void** bp = cursor->bp;
  void*  sp = cursor->sp;
  void*  pc = cursor->pc_unnorm;
  unwind_interval* uw = (unwind_interval *)cursor->intvl;
  
  TMSG(UNW,"step_sp: cursor { bp=%p, sp=%p, pc=%p }", bp, sp, pc);
  if (MYDBG) { dump_ui(uw, 0); }

  void** next_bp = NULL;
  void** next_sp = (void **)(sp + uw->sp_ra_pos);
  void*  ra_loc  = (void*) next_sp;
  void*  next_pc  = *next_sp;

  TMSG(UNW,"  step_sp: potential next cursor next_sp=%p ==> next_pc = %p",
       next_sp, next_pc);

  if (uw->bp_status == BP_UNCHANGED){
    next_bp = bp;
    TMSG(UNW,"  step_sp: unwind step has BP_UNCHANGED ==> next_bp=%p", next_bp);
  }
  else {
    //-----------------------------------------------------------
    // reload the candidate value for the caller's BP from the 
    // save area in the activation frame according to the unwind 
    // information produced by binary analysis
    //-----------------------------------------------------------
    next_bp = (void **)(sp + uw->sp_bp_pos);
    TMSG(UNW,"  step_sp: unwind next_bp loc = %p", next_bp);
    next_bp  = *next_bp; 
    TMSG(UNW,"  step_sp: sp unwind next_bp val = %p", next_bp);

  }
  next_sp += 1;
  ip_normalized_t next_pc_norm = ip_normalized_NULL;
  cursor->intvl = hpcrun_addr_to_interval(((char *)next_pc) - 1,
					  next_pc, &next_pc_norm);

  if (! cursor->intvl){
    if (((void *)next_sp) >= monitor_stack_bottom()){
      TMSG(UNW,"  step_sp: STEP_STOP_WEAK, no next interval and next_sp >= stack bottom,"
	   " so stop unwind ...");
      return STEP_STOP_WEAK;
    }
    else {
      TMSG(UNW,"  sp STEP_ERROR: no next interval, step fails");
      return STEP_ERROR;
    }
  }
  else {
    // sanity check to avoid infinite unwind loop
    if (next_sp <= cursor->sp){
      TMSG(INTV_ERR,"@ pc = %p. sp unwind does not advance stack." 
	   " New sp = %p, old sp = %p", cursor->pc_unnorm, next_sp,
	   cursor->sp);
      
      return STEP_ERROR;
    }
    unwind_interval* uw = (unwind_interval *)cursor->intvl;
    if ((RA_BP_FRAME == uw->ra_status) ||
	(RA_STD_FRAME == uw->ra_status)) { // Makes sense to sanity check BP, do it
      //-----------------------------------------------------------
      // if value of BP reloaded from the save area does not point 
      // into the stack, then it cannot possibly be useful as a frame 
      // pointer in the caller or any of its ancesters.
      //
      // if the value in the BP register points into the stack, then 
      // it might be useful as a frame pointer. in this case, we have 
      // nothing to lose by assuming that our binary analysis for 
      // unwinding might have been mistaken and that the value in 
      // the register is the one we might want. 
      //
      // 19 December 2007 - John Mellor-Crummey
      //-----------------------------------------------------------
    
      if (((unsigned long) next_bp < (unsigned long) sp) && 
	  ((unsigned long) bp > (unsigned long) sp)){
	next_bp = bp;
	TMSG(UNW,"  step_sp: unwind bp sanity check fails."
	     " Resetting next_bp to current bp = %p", next_bp);
      }
    }
    cursor->pc_unnorm = next_pc;
    cursor->bp 	      = next_bp;
    cursor->sp 	      = next_sp;
    cursor->ra_loc    = ra_loc;
    cursor->pc_norm   = next_pc_norm;
  }

  TMSG(UNW,"  step_sp: STEP_OK, has_intvl=%d, bp=%p, sp=%p, pc=%p",
	   cursor->intvl != NULL, next_bp, next_sp, next_pc);
  return STEP_OK;
}
Ejemplo n.º 5
0
static step_state
hpcrun_unw_step_real(hpcrun_unw_cursor_t* cursor)
{

  cursor->fence = hpcrun_check_fence(cursor->pc_unnorm);

  //-----------------------------------------------------------
  // check if we have reached the end of our unwind, which is
  // demarcated with a fence. 
  //-----------------------------------------------------------
  if (fence_stop(cursor->fence)) {
    TMSG(UNW,"unw_step: STEP_STOP, current pc in monitor fence pc=%p\n", cursor->pc_unnorm);
    return STEP_STOP;
  }

  // current frame  
  void** bp = cursor->bp;
  void*  sp = cursor->sp;
  void*  pc = cursor->pc_unnorm;
  unwind_interval* uw = (unwind_interval *)cursor->intvl;

  int unw_res;

  if (!uw){
    TMSG(UNW, "unw_step: invalid unw interval for cursor, trolling ...");
    TMSG(TROLL, "Troll due to Invalid interval for pc %p", pc);
    update_cursor_with_troll(cursor, 0);
    return STEP_TROLL;
  }

  switch (uw->ra_status){
  case RA_SP_RELATIVE:
    unw_res = unw_step_sp(cursor);
    break;
    
  case RA_BP_FRAME:
    unw_res = unw_step_bp(cursor);
    break;
    
  case RA_STD_FRAME:
    unw_res = unw_step_std(cursor);
    break;

  default:
    EMSG("unw_step: ILLEGAL UNWIND INTERVAL");
    dump_ui((unwind_interval *)cursor->intvl, 0);
    assert(0);
  }
  if (unw_res == STEP_STOP_WEAK) unw_res = STEP_STOP; 

  if (unw_res != STEP_ERROR) {
    return unw_res;
  }
  
  TMSG(TROLL,"unw_step: STEP_ERROR, pc=%p, bp=%p, sp=%p", pc, bp, sp);
  dump_ui_troll(uw);

  if (ENABLED(TROLL_WAIT)) {
    fprintf(stderr,"Hit troll point: attach w gdb to %d\n"
            "Maybe call dbg_set_flag(DBG_TROLL_WAIT,0) after attached\n",
	    getpid());
    
    // spin wait for developer to attach a debugger and clear the flag 
    while(DEBUG_WAIT_BEFORE_TROLLING);  
  }
  
  update_cursor_with_troll(cursor, 1);
  return STEP_TROLL;
}