示例#1
0
void print_stack(struct object_heap* oh) {
  struct Interpreter* i = oh->cached.interpreter;
  word_t size = i->stackPointer;
  word_t j;
  for (j=0; j < size; j++) {
    fprintf(stderr, "stack[%" PRIdPTR "] = ", j);
    print_detail(oh, i->stack->elements[j]);
  }
}
示例#2
0
static int
handle_cfi (Dwfl *dwfl, const char *which, Dwarf_CFI *cfi,
	    GElf_Addr pc, struct stuff *stuff)
{
  int result = dwarf_cfi_addrframe (cfi, pc - stuff->bias, &stuff->frame);
  if (result != 0)
    {
      error (0, 0, "dwarf_addrframe (%s): %s", which, dwfl_errmsg (-1));
      return 1;
    }

  Dwarf_Addr start = pc;
  Dwarf_Addr end = pc;
  bool signalp;
  int ra_regno = dwarf_frame_info (stuff->frame, &start, &end, &signalp);
  if (ra_regno >= 0)
    {
      start += stuff->bias;
      end += stuff->bias;
    }

  printf ("%s has %#" PRIx64 " => [%#" PRIx64 ", %#" PRIx64 "):\n",
	  which, pc, start, end);

  if (ra_regno < 0)
    printf ("\treturn address register unavailable (%s)\n",
	    dwarf_errmsg (0));
  else
    printf ("\treturn address in reg%u%s\n",
	    ra_regno, signalp ? " (signal frame)" : "");

  Dwarf_Op *cfa_ops;
  size_t cfa_nops;
  result = dwarf_frame_cfa (stuff->frame, &cfa_ops, &cfa_nops);

  printf ("\tCFA ");
  print_detail (result, cfa_ops, cfa_nops, stuff->bias);

  (void) dwfl_module_register_names (dwfl_addrmodule (dwfl, pc),
				     &print_register, stuff);

  return 0;
}
示例#3
0
static int
print_register (void *arg,
		int regno,
		const char *setname,
		const char *prefix,
		const char *regname,
		int bits __attribute__ ((unused)),
		int type __attribute__ ((unused)))
{
  struct stuff *stuff = arg;

  printf ("\t%s reg%u (%s%s): ", setname, regno, prefix, regname);

  Dwarf_Op ops_mem[2];
  Dwarf_Op *ops;
  size_t nops;
  int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops);
  print_detail (result, ops, nops, stuff->bias);

  return DWARF_CB_OK;
}
示例#4
0
void print_backtrace(struct object_heap* oh) {
  word_t depth = 0, detail_depth = -1 /*raise this to print verbose args in stack longer*/;
  struct Interpreter* i = oh->cached.interpreter;
  struct Closure* closure = (struct Closure*)i->method;
  word_t codePointer = i->codePointer;
  word_t fp = i->framePointer;
  word_t sp = i->stackPointer;
  word_t codeSize = i->codeSize;
  word_t resultStackPointer = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_RESULT_STACK_POINTER]);
  struct LexicalContext* lc = (struct LexicalContext*)i->stack->elements[fp - FRAME_OFFSET_LEXICAL_CONTEXT];;
  fprintf(stderr, "printing backtrace from fp=%" PRIdPTR ", sp=%" PRIdPTR "\n", fp, i->stackPointer);
  do {
    word_t j;
    struct Object** vars;
    word_t input_count = object_to_smallint(closure->method->inputVariables);
    word_t local_count = object_to_smallint(closure->method->localVariables);
    vars = (closure->method->heapAllocate == oh->cached.true_object)? (&lc->variables[0]) : (&i->stack->elements[fp]);
    fprintf(stderr, "------------------------------\n");
    fprintf(stderr, "FP: %" PRIdPTR "\n", fp);
    fprintf(stderr, "SP: %" PRIdPTR "\n", sp);
    fprintf(stderr, "IP: %" PRIdPTR "/%" PRIdPTR "\n", codePointer, codeSize);
    fprintf(stderr, "result: %" PRIdPTR "\n", resultStackPointer);
    fprintf(stderr, "code: %p\n", closure->method->code);
    fprintf(stderr, "selector #"); print_byte_array((struct Object*)(closure->method->selector)); fprintf(stderr, "\n");
    fprintf(stderr, "regs: %" PRIdPTR "\n", object_to_smallint(closure->method->registerCount));
    fprintf(stderr, "heap alloc: %s\n", (closure->method->heapAllocate == oh->cached.true_object)? "true" : "false");

    for (j = 0; j < input_count; j++) {
      fprintf(stderr, "arg[%" PRIdPTR "] (%p) = ", j, (void*)vars[j]);
      if (depth > detail_depth) {
        print_type(oh, vars[j]);
      } else {
        print_detail(oh, vars[j]);
      }
    }
    if (closure->method->heapAllocate == oh->cached.true_object) {
      for (j = 0; j < local_count; j++) {
        fprintf(stderr, "var[%" PRIdPTR "] (%p)= ", j, (void*)lc->variables[j]);
        if (depth > detail_depth) {
          print_type(oh, lc->variables[j]);
        } else {
          print_detail(oh, lc->variables[j]);
        }
      }
    } else {
      for (j = input_count; j < input_count + local_count; j++) {
        fprintf(stderr, "var[%" PRIdPTR "] (%p) = ", j - input_count, (void*)vars[j]);
        if (depth > detail_depth) {
          print_type(oh, vars[j]);
        } else {
          print_detail(oh, vars[j]);
        }
      }
    }

    /*order matters here*/
    codePointer = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_CODE_POINTER]);
    fp = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_PREVIOUS_FRAME_POINTER]);
    if (fp < FUNCTION_FRAME_SIZE) break;
    sp = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_BEFORE_CALL_STACK_POINTER]);
    resultStackPointer = object_to_smallint(i->stack->elements[fp - FRAME_OFFSET_RESULT_STACK_POINTER]);
    closure = (struct Closure*)i->stack->elements[fp - FRAME_OFFSET_METHOD];
    lc = (struct LexicalContext*)i->stack->elements[fp - FRAME_OFFSET_LEXICAL_CONTEXT];
    codeSize = array_size(closure->method->code);
    depth++;
  } while (fp >= FUNCTION_FRAME_SIZE);
}
示例#5
0
/*
 * This is the main dispatch function
 *
 */
struct MethodDefinition* method_dispatch_on(struct object_heap* oh, struct Symbol* name,
                                            struct Object* arguments[], word_t arity, struct Object* resendMethod) {

  struct MethodDefinition *dispatch, *bestDef;
  struct Object* slotLocation;
  word_t bestRank, depth, delegationCount, resendRank, restricted, i;


#ifdef PRINT_DEBUG_DISPATCH
  fprintf(stderr, "dispatch to: '");
  print_symbol(name);
  fprintf(stderr, "' (arity: %" PRIdPTR ")\n", arity);
  for (i = 0; i < arity; i++) {
    fprintf(stderr, "arguments[%" PRIdPTR "] (%p) = ", i, (void*)arguments[i]); print_type(oh, arguments[i]);
  }
  /*  fprintf(stderr, "resend: "); print_object(resendMethod);*/
#endif

  dispatch = NULL;
  slotLocation = NULL;

#ifndef SLATE_DISABLE_METHOD_CACHE
  if (resendMethod == NULL && arity <= METHOD_CACHE_ARITY) {
    dispatch = method_check_cache(oh, name, arguments, arity);
    if (dispatch != NULL) return dispatch;
  }
#endif

  oh->current_dispatch_id++;
  bestRank = 0;
  bestDef = NULL;
  resendRank = ((resendMethod == NULL) ? WORDT_MAX : 0);

  for (i = 0; i < arity; i++) {
    struct Object *obj;
    struct Map* map;
    struct Object* arg = arguments[i];
    delegationCount = 0;
    depth = 0;
    restricted = WORDT_MAX; /*pointer in delegate_stack (with sp of delegateCount) to where we don't trace further*/
    
    do {
      /* Set up obj to be a pointer to the object, or SmallInteger if it's
         a direct SmallInt. */
      if (object_is_smallint(arg)) {
        obj = get_special(oh, SPECIAL_OOP_SMALL_INT_PROTO);
      } else {
        obj = arg;
      }
      /* Identify the map, and update its dispatchID and reset the visited mask
         if it hasn't been visited during this call already. */
      map = obj->map;

      if (map->dispatchID != oh->current_dispatch_id) {
        map->dispatchID = oh->current_dispatch_id;
        map->visitedPositions = 0;
      }

      /* we haven't been here before */
      if ((map->visitedPositions & (1 << i)) == 0) {

        struct RoleEntry* role;

        /* If the map marks an obj-meta transition and the top of the stack
           is not the original argument, then mark the restriction point at
           the top of the delegation stack. */

        if (((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION) && (arg != arguments[i])) {
          restricted = delegationCount;
        }
        map->visitedPositions |= (1 << i);
        role = role_table_entry_for_name(oh, map->roleTable, name);
        while (role != NULL) {
          if ((object_to_smallint(role->rolePositions) & (1 << i)) != 0) {
            struct MethodDefinition* def = role->methodDefinition;
            /* If the method hasn't been visited this time, mark it
               so and clear the other dispatch marks.*/
            if (def->dispatchID != oh->current_dispatch_id) {
              def->dispatchID = oh->current_dispatch_id;
              def->foundPositions = 0;
              def->dispatchRank = 0;
            }
            /*If the method hasn't been found at this position...*/
            if ((def->foundPositions & (1 << i)) == 0) {
              /*fix*/

              def->dispatchRank |= ((31 - depth) << ((5 - i) * 5));
              def->foundPositions |= (1 << i);

#ifdef PRINT_DEBUG_FOUND_ROLE
              fprintf(stderr, "found role index %" PRIdPTR " <%p> for '%s' foundPos: %" PRIuPTR "x dispatchPos: %" PRIuPTR "x\n",
                     i,
                     (void*) role,
                     ((struct Symbol*)(role->name))->elements, def->foundPositions, def->dispatchPositions);
#endif

              if (def->method == resendMethod) {
                struct RoleEntry* rescan = role_table_entry_for_name(oh, map->roleTable, name);
                resendRank = def->dispatchRank;
                while (rescan != role) {
                  struct MethodDefinition* redef = rescan->methodDefinition;
                  if (redef->foundPositions == redef->dispatchPositions &&
                      (dispatch == NULL || redef->dispatchRank <= resendRank)) {
                    dispatch = redef;
                    slotLocation = obj;
                    if (redef->dispatchRank > bestRank) {
                      bestRank = redef->dispatchRank;
                      bestDef = redef;
                    }
                  }
                  if (rescan->nextRole == oh->cached.nil) {
                    rescan = NULL;
                  } else {
                    rescan = &map->roleTable->roles[object_to_smallint(rescan->nextRole)];
                  }
                  
                }

              } else /*not a resend*/ {
                if (def->foundPositions == def->dispatchPositions &&
                    (dispatch == NULL || def->dispatchRank > dispatch->dispatchRank) &&
                    def->dispatchRank <= resendRank) {
                  dispatch = def;
                  slotLocation = obj;
                  if (def->dispatchRank > bestRank) {
                    bestRank = def->dispatchRank;
                    bestDef = def;
                  }
                }
              }
              if (def->dispatchRank >= bestRank && def != bestDef) {
                bestRank = def->dispatchRank;
                bestDef = NULL;
              }
            }
            
          }
          role = ((role->nextRole == oh->cached.nil) ? NULL : &map->roleTable->roles[object_to_smallint(role->nextRole)]);
        } /*while role != NULL*/

        if (depth > 31) { /*fix wordsize*/
          assert(0);
        }
        if (dispatch != NULL && bestDef == dispatch) {
          if (dispatch->slotAccessor != oh->cached.nil) {
            arguments[0] = slotLocation;
            /*do we need to try to do a heap_store_into?*/
#ifdef PRINT_DEBUG_DISPATCH_SLOT_CHANGES
            fprintf(stderr, "arguments[0] changed to slot location: \n");
            print_detail(oh, arguments[0]);
#endif
          }
          if (resendMethod == 0 && arity <= METHOD_CACHE_ARITY) method_save_cache(oh, dispatch, name, arguments, arity);
          return dispatch;
        }
        
        depth++;


        /* We add the delegates to the list when we didn't just finish checking a restricted object*/
        if (delegationCount <= restricted && array_size(map->delegates) > 0) {
          struct OopArray* delegates = map->delegates;
          word_t offset = object_array_offset((struct Object*)delegates);
          word_t limit = object_total_size((struct Object*)delegates);
          for (; offset != limit; offset += sizeof(word_t)) {
            struct Object* delegate = object_slot_value_at_offset((struct Object*)delegates, offset);
            if (delegate != oh->cached.nil) {
              oh->delegation_stack[delegationCount++] = delegate;
            }
          }
        }
        
      } /*end haven't been here before*/

      

      delegationCount--;
      if (delegationCount < restricted) restricted = WORDT_MAX; /*everything is unrestricted now*/

      if (delegationCount < 0 || delegationCount >= DELEGATION_STACK_SIZE) break;

      arg = oh->delegation_stack[delegationCount];


    } while (1);

  }


  if (dispatch != NULL && dispatch->slotAccessor != oh->cached.nil) {
    /*check heap store into?*/
    arguments[0] = slotLocation;
#ifdef PRINT_DEBUG_DISPATCH_SLOT_CHANGES
            fprintf(stderr, "arguments[0] changed to slot location: \n");
            print_detail(oh, arguments[0]);
#endif

  }

#ifndef SLATE_DISABLE_METHOD_CACHE
  if (dispatch != NULL && resendMethod == 0 && arity < METHOD_CACHE_ARITY) {
    method_save_cache(oh, dispatch, name, arguments, arity);
  }
#endif

  return dispatch;
}
示例#6
0
static void detail(char *toks[], int t, struct config *conf, int row, int col)
{
	int x=0;
	char msg[1024]="";
	const char *tmp=NULL;
	if(toks[0])
	{
		snprintf(msg, sizeof(msg), "Client: %s", toks[0]);
		print_line(msg, x++, col);
	}
	if(toks[1])
	{
		switch(*(toks[1]))
		{
			case STATUS_IDLE:
			{
				print_line("Status: idle", x++, col);
				show_all_backups(toks, t, &x, col);
				return;
			}
			case STATUS_SERVER_CRASHED:
			{
				print_line("Status: server crashed", x++, col);
				show_all_backups(toks, t, &x, col);
				return;
			}
			case STATUS_CLIENT_CRASHED:
			{
				print_line("Status: client crashed", x++, col);
				show_all_backups(toks, t, &x, col);
				return;
			}
			case STATUS_RUNNING:
			{
				if(toks[2])
				{
					char msg[64]="";
					if(t<3) return;
					snprintf(msg, sizeof(msg),
						"Status: running (%s)",
						running_status_to_text(
							*(toks[2])));
					print_line(msg, x++, col);
				}
				break;
			}
		}
	}
	print_line("", x++, col);
	table_header(&x, col);
	if(t>4) print_detail("Files", toks[4], &x, col, 0);
	if(t>5) print_detail("Encrypted files", toks[5], &x, col, 0);
	if(t>6) print_detail("Meta data", toks[6], &x, col, 0);
	if(t>7) print_detail("Encrypted meta data", toks[7], &x, col, 0);
	if(t>8) print_detail("Directories", toks[8], &x, col, 0);
	if(t>9) print_detail("Soft links", toks[9], &x, col, 0);
	if(t>10) print_detail("Hard links", toks[10], &x, col, 0);
	if(t>11) print_detail("Special files", toks[11], &x, col, 0);
	if(t>12)
	{
		print_detail("Total", toks[12], &x, col, 1);
	}
	print_line("", x++, col);
	if(t>14) print_detail2("Warnings", toks[14], "", &x, col);

	if(t>15)
	{
		tmp=bytes_to_human_str(toks[15]);
		print_detail2("Bytes expected", toks[15], tmp, &x, col);
	}
	if(t>16)
	{	
		tmp=bytes_to_human_str(toks[16]);
		print_detail2("Bytes in backup", toks[16], tmp, &x, col);
	}
	if(t>17)
	{
		tmp=bytes_to_human_str(toks[17]);
		print_detail2("Bytes received", toks[17], tmp, &x, col);
	}
	if(t>18)
	{
		tmp=bytes_to_human_str(toks[18]);
		print_detail2("Bytes sent", toks[18], tmp, &x, col);
	}
	if(t>19)
	{
		long start=0;
		time_t now=0;
		time_t diff=0;
		now=time(NULL);
		start=atol(toks[19]);
		diff=now-start;

		print_detail2("Start time", getdatestr(start), " ", &x, col);
		print_detail2("Time taken", time_taken(diff), " ", &x, col);

		if(diff>0)
		{
			unsigned long long bytesleft=0;
			unsigned long long byteswant=0;
			unsigned long long bytesgot=0;
			float bytespersec=0;
			byteswant=strtoull(toks[15], NULL, 10);
			bytesgot=strtoull(toks[16], NULL, 10);
			bytespersec=(float)(bytesgot/diff);
			bytesleft=byteswant-bytesgot;
			if(bytespersec>0)
			{
				time_t timeleft=0;
				timeleft=(time_t)(bytesleft/bytespersec);
				print_detail2("Time left",
					time_taken(timeleft), " ", &x, col);
			}
		}
	}
	if(t>20 && toks[20])
	{
#ifdef HAVE_NCURSES_H
		if(actg==ACTION_STATUS)
		{
			printw("\n%s\n", toks[20]);
			return;
		}
#else
		printf("\n%s\n", toks[20]);
#endif
	}
}