Esempio n. 1
0
static void
handle_arch_sysret(Event *event) {
	debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
	if (event->proc->state != STATE_IGNORED) {
		if (opt_T || options.summary) {
			calc_time_spent(event->proc);
		}
		if (options.syscalls) {
			output_right(LT_TOF_SYSCALLR, event->proc,
					arch_sysname(event->proc, event->e_un.sysnum));
		}
		callstack_pop(event->proc);
	}
	continue_process(event->proc->pid);
}
Esempio n. 2
0
static void
handle_sysret(Event *event) {
	debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
	if (event->proc->state != STATE_IGNORED) {
		if (opt_T || options.summary) {
			calc_time_spent(event->proc);
		}
		if (options.syscalls) {
			output_right(LT_TOF_SYSCALLR, event->proc,
					sysname(event->proc, event->e_un.sysnum));
		}
		assert(event->proc->callstack_depth > 0);
		unsigned d = event->proc->callstack_depth - 1;
		assert(event->proc->callstack[d].is_syscall);
		callstack_pop(event->proc);
	}
	continue_after_syscall(event->proc, event->e_un.sysnum, 1);
}
Esempio n. 3
0
static void
handle_breakpoint(Event *event) {
	int i, j;
	Breakpoint *sbp;
	Process *leader = event->proc->leader;

	/* The leader has terminated.  */
	if (leader == NULL) {
		continue_process(event->proc->pid);
		return;
	}

	debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)", event->proc->pid, event->e_un.brk_addr);
	debug(2, "event: breakpoint (%p)", event->e_un.brk_addr);

#ifdef __powerpc__
	/* Need to skip following NOP's to prevent a fake function from being stacked.  */
	long stub_addr = (long) get_count_register(event->proc);
	Breakpoint *stub_bp = NULL;
	char nop_instruction[] = PPC_NOP;

	stub_bp = address2bpstruct(leader, event->e_un.brk_addr);

	if (stub_bp) {
		unsigned char *bp_instruction = stub_bp->orig_value;

		if (memcmp(bp_instruction, nop_instruction,
			    PPC_NOP_LENGTH) == 0) {
			if (stub_addr != (long) event->e_un.brk_addr) {
				set_instruction_pointer (event->proc, event->e_un.brk_addr + 4);
				continue_process(event->proc->pid);
				return;
			}
		}
	}
#endif

	for (i = event->proc->callstack_depth - 1; i >= 0; i--) {
		if (event->e_un.brk_addr ==
		    event->proc->callstack[i].return_addr) {
#ifdef __powerpc__
			/*
			 * PPC HACK! (XXX FIXME TODO)
			 * The PLT gets modified during the first call,
			 * so be sure to re-enable the breakpoint.
			 */
			unsigned long a;
			struct library_symbol *libsym =
			    event->proc->callstack[i].c_un.libfunc;
			void *addr = sym2addr(event->proc, libsym);

			if (libsym->plt_type != LS_TOPLT_POINT) {
				unsigned char break_insn[] = BREAKPOINT_VALUE;

				sbp = address2bpstruct(leader, addr);
				assert(sbp);
				a = ptrace(PTRACE_PEEKTEXT, event->proc->pid,
					   addr);

				if (memcmp(&a, break_insn, BREAKPOINT_LENGTH)) {
					sbp->enabled--;
					insert_breakpoint(event->proc, addr,
							  libsym, 1);
				}
			} else {
				sbp = dict_find_entry(leader->breakpoints, addr);
				/* On powerpc, the breakpoint address
				   may end up being actual entry point
				   of the library symbol, not the PLT
				   address we computed.  In that case,
				   sbp is NULL.  */
				if (sbp == NULL || addr != sbp->addr) {
					insert_breakpoint(event->proc, addr,
							  libsym, 1);
				}
			}
#elif defined(__mips__)
			void *addr = NULL;
			struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
			struct library_symbol *new_sym;
			assert(sym);
			addr = sym2addr(event->proc, sym);
			sbp = dict_find_entry(leader->breakpoints, addr);
			if (sbp) {
				if (addr != sbp->addr) {
					insert_breakpoint(event->proc, addr, sym, 1);
				}
			} else {
				new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
				memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
				new_sym->next = leader->list_of_symbols;
				leader->list_of_symbols = new_sym;
				insert_breakpoint(event->proc, addr, new_sym, 1);
			}
#endif
			for (j = event->proc->callstack_depth - 1; j > i; j--) {
				callstack_pop(event->proc);
			}
			if (event->proc->state != STATE_IGNORED) {
				if (opt_T || options.summary) {
					calc_time_spent(event->proc);
				}
			}
			event->proc->return_addr = event->e_un.brk_addr;
			if (event->proc->state != STATE_IGNORED) {
				mock_return(LT_TOF_FUNCTIONR, event->proc,
						event->proc->callstack[i].c_un.libfunc->name);
				output_right(LT_TOF_FUNCTIONR, event->proc,
						event->proc->callstack[i].c_un.libfunc->name);
			}
			callstack_pop(event->proc);
			sbp = address2bpstruct(leader, event->e_un.brk_addr);
			continue_after_breakpoint(event->proc, sbp);
			return;
		}
	}

	if ((sbp = address2bpstruct(leader, event->e_un.brk_addr))) {
		if (sbp->libsym == NULL) {
			continue_after_breakpoint(event->proc, sbp);
			return;
		}

		if (strcmp(sbp->libsym->name, "") == 0) {
			debug(DEBUG_PROCESS, "Hit _dl_debug_state breakpoint!\n");
			arch_check_dbg(leader);
		}

		if (event->proc->state != STATE_IGNORED) {
			event->proc->stack_pointer = get_stack_pointer(event->proc);
			event->proc->return_addr =
				get_return_addr(event->proc, event->proc->stack_pointer);
			callstack_push_symfunc(event->proc, sbp->libsym);
			output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym->name);
		}
#ifdef PLT_REINITALISATION_BP
		if (event->proc->need_to_reinitialize_breakpoints
		    && (strcmp(sbp->libsym->name, PLTs_initialized_by_here) ==
			0))
			reinitialize_breakpoints(leader);
#endif

		continue_after_breakpoint(event->proc, sbp);
		return;
	}

	if (event->proc->state != STATE_IGNORED && !options.no_plt) {
		output_line(event->proc, "unexpected breakpoint at %p",
				(void *)event->e_un.brk_addr);
	}
	continue_process(event->proc->pid);
}
Esempio n. 4
0
/* CALL FUNCTION HOOK */
static void callhook(lua_State *L, lua_Function func, char *file, int line) {
    check_start(L);
    Meta **array = get_metadata_array(L);
    if (!array) return; // check if exists (call profile_stop ?)

    if (STACK_INDEX > MEM_BLOCKSIZE - 1) {
        // Reached memory limit, relocated to double.
        int blocksize = MEM_BLOCKSIZE * 2;

        array = realloc(array, blocksize * sizeof(Meta **));

        if (array) {
            lua_unref(L, META_REF); // Remove the old reference (new block of memory).
            lua_pushuserdata(L, array); // Saves the new reference.
            META_REF = lua_ref(L, 1);
            MEM_BLOCKSIZE = blocksize; // Updates the size of the memory block.
        } else {
            lua_error(L, "profiler: out of memory!");
            return; // suppress inspect
        }
    }

    char *func_name;
    char *func_scope;

    if (lua_isfunction(L, func)) {
        func_scope = lua_getobjname(L, func, &func_name);
        Meta *meta = (Meta *) malloc(sizeof(Meta));

        meta->fun_name = func_name ? func_name : "unnamed";
        if (func_scope && strlen(func_scope) > 0) {
            meta->fun_scope = func_scope;
        } else {
            meta->fun_scope = "unknown";
        }
        meta->func_file = file ? file : "unnamed";
        meta->stack_level = STACK_SIZE;
        meta->line = line;

        Children *children = (Children *) malloc(sizeof(Children));
        meta->children = children;
        children->index = 0;
        children->list = NULL;
        children->size = 20;

        Measure *measure = (Measure *) malloc(sizeof(Measure));
        measure->begin = clock();
        meta->measure = measure;

        stack_record.meta = meta;
        push(&stack, stack_record);

        if (STACK_SIZE == 0) {
            array[STACK_INDEX] = meta;
            STACK_INDEX++;
        }
        STACK_SIZE++;

    } else if (STACK_SIZE > 0) {
        STACK_RECORD top_record = pop(&stack);
        STACK_RECORD *new_record = next(&stack);

        Meta *meta = top_record.meta;
        meta->measure->end = clock();
        meta->measure->time_spent = calc_time_spent(meta->measure);

        if (new_record != NULL && meta->measure->time_spent >= PROFILE_RECORD_TIME) {
            Meta *_meta = new_record->meta;
            if (!_meta->children->list) { // already allocated ?
                _meta->children->list = (Meta **) malloc(_meta->children->size * sizeof(Meta **));
                if (!_meta->children->list) lua_error(L, "out of memory");
            }
            if (_meta->children->index > _meta->children->size - 1) {
                _meta->children->size *= 2; // more
                _meta->children->list = (Meta **) realloc(_meta->children->list,
                                                          _meta->children->size * sizeof(Meta **));
                if (!_meta->children->list) lua_error(L, "out of memory");
            }
            _meta->children->list[_meta->children->index] = meta;
            _meta->children->index++;
        }
        STACK_SIZE--;
    }
}