Пример #1
0
/* We transform string loops into regular loops so we can more easily
 * monitor every memory reference they make.
 */
static dr_emit_flags_t
event_bb_app2app(void *drcontext, void *tag, instrlist_t *bb, bool for_trace,
                 bool translating)
{
    if (!drutil_expand_rep_string(drcontext, bb)) {
        DR_ASSERT(false);
        /* in release build, carry on: we'll just miss per-iter refs */
    }
    drx_tail_pad_block(drcontext, bb);
    return DR_EMIT_DEFAULT;
}
Пример #2
0
static void
event_exit(void)
{
#ifdef SHOW_RESULTS
    /* Display the results! */
    char msg[512];
    int len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                          "Inlining results:\n"
                          "  Number of traces: %d\n"
                          "  Number of complete inlines: %d\n",
                          num_traces, num_complete_inlines);
    DR_ASSERT(len > 0);
    msg[sizeof(msg)/sizeof(msg[0])-1] = '\0';
    DISPLAY_STRING(msg);
#endif
    hashtable_delete(&head_table);
    if (!drmgr_unregister_bb_instrumentation_event(event_analyze_bb))
        DR_ASSERT(false);
    drmgr_exit();
}
Пример #3
0
app_pc
table_alloc_bytes(umbra_info_t *info, int size)
{
    app_pc ptr;

    DR_ASSERT(size >= 0 && 
              (info->table.bytes_ptr + size) < 
              (info->table.bytes_table + MAX_BYTES_TABLE_SIZE));
    ptr = info->table.bytes_ptr;
    info->table.bytes_ptr += size;
    return ptr;
}
Пример #4
0
static void
event_exit(void)
{
    if (!drmgr_unregister_thread_init_event(event_thread_init) ||
        !drmgr_unregister_bb_insertion_event(event_app_instruction) ||
        drreg_exit() != DRREG_SUCCESS)
        DR_ASSERT(false);

    drx_buf_free(buf);
    drmgr_exit();
    drx_exit();
}
Пример #5
0
static void
event_exit(void)
{
    show_results();
    if (!drmgr_unregister_cls_field(event_thread_context_init,
                                    event_thread_context_exit,
                                    tcls_idx) ||
        !drmgr_unregister_pre_syscall_event(event_pre_syscall) ||
        !drmgr_unregister_post_syscall_event(event_post_syscall))
        DR_ASSERT(false && "failed to unregister");
    drmgr_exit();
}
Пример #6
0
static void 
event_exit(void)
{
    char msg[512];
    int len;
    len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                      "Instrumentation results: %llu instructions executed\n",
                      global_count);
    DR_ASSERT(len > 0);
    NULL_TERMINATE(msg);
    DISPLAY_STRING(msg);
}
Пример #7
0
static void
wrap_post(void *wrapcxt, void *user_data)
{
    size_t sz = (size_t) user_data;
    /* test out-of-memory by having a random moderately-large alloc fail */
    if (sz > 1024 && dr_get_random_value(1000) < 10) {
        bool ok = drwrap_set_retval(wrapcxt, NULL);
        DR_ASSERT(ok);
        dr_mutex_lock(max_lock);
        malloc_oom++;
        dr_mutex_unlock(max_lock);
    }
}
Пример #8
0
file_t 
umbra_open_proc_log(process_id_t pid)
{
#ifdef LINUX_KERNEL
    return our_stdout;
#else
    char   name[128];
    int    len;
    file_t logfile;

    /* XXX: Windows need a absolute path */
    name[0] = '\0';
    len = dr_snprintf(name, sizeof(name)/sizeof(name[0]),
                      "umbra.%s.%d.proc.log", 
                      dr_get_application_name(), pid);
    DR_ASSERT(len > 0);
    name[sizeof(name)/sizeof(name[0])-1] = '\0';
    logfile = dr_open_file(name, DR_FILE_READ | DR_FILE_WRITE_APPEND);
    DR_ASSERT(logfile != INVALID_FILE);
    return logfile;
#endif
}
Пример #9
0
static void post_func_cb(void * wrapcxt, void ** user_data){
	DEBUG_PRINT("funcwrap - post_func_cb\n");
	per_thread_t * data = drmgr_get_tls_field(dr_get_current_drcontext(), tls_index);
	data->nesting--;
	//dr_unlink_flush_region(0, ~((ptr_uint_t)0));
	DR_ASSERT(data->nesting >= 0); 
	if (data->nesting == 0){
		data->filter_func = false;
	}
	DEBUG_PRINT("funcwrap - post_func_cb done \n");
	

}
Пример #10
0
static void
event_thread_init(void *drcontext)
{
    file_t log;
    log = log_file_open(client_id, drcontext, NULL /* using client lib path */,
                        "cbrtrace",
#ifndef WINDOWS
                        DR_FILE_CLOSE_ON_FORK |
#endif
                        DR_FILE_ALLOW_LARGE);
    DR_ASSERT(log != INVALID_FILE);
    dr_set_tls_field(drcontext, (void *)(ptr_uint_t)log);
}
Пример #11
0
static void
module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
{
    app_pc towrap = (app_pc)dr_get_proc_address(mod->handle, "SSL_write");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_write, NULL);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap SSL_write\n");
            DR_ASSERT(ok);
        }
    }

    towrap = (app_pc)dr_get_proc_address(mod->handle, "SSL_read");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_read, wrap_post_SSL_read);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap SSL_read\n");
            DR_ASSERT(ok);
        }
    }

    towrap = (app_pc)dr_get_proc_address(mod->handle, "gnutls_record_send");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_write, NULL);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap gnutls_record_send\n");
            DR_ASSERT(ok);
        }
    }

    towrap = (app_pc)dr_get_proc_address(mod->handle, "gnutls_record_recv");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_read, wrap_post_SSL_read);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap gnutls_record_recv\n");
            DR_ASSERT(ok);
        }
    }
}
Пример #12
0
static dr_emit_flags_t
event_app_analysis(void *drcontext, void *tag, instrlist_t *bb, bool for_trace,
                   bool translating, void **user_data)
{
    per_thread_t *data = drmgr_get_tls_field(drcontext, tls_idx);

    *user_data = (void *)&data->reg_addr;
    /* If we have an outstanding write, that means we did not correctly handle a case
     * where there was a write but no fall-through NOP or terminating instruction in
     * the previous basic block.
     */
    DR_ASSERT(data->reg_addr == DR_REG_NULL);
    return DR_EMIT_DEFAULT;
}
Пример #13
0
static void
insert_save_addr(void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t ref,
                 reg_id_t reg_ptr, reg_id_t reg_addr)
{
    bool ok;
    /* we use reg_ptr as scratch to get addr */
    ok = drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg_addr, reg_ptr);
    DR_ASSERT(ok);
    insert_load_buf_ptr(drcontext, ilist, where, reg_ptr);
    MINSERT(ilist, where,
            XINST_CREATE_store(drcontext,
                               OPND_CREATE_MEMPTR(reg_ptr, offsetof(mem_ref_t, addr)),
                               opnd_create_reg(reg_addr)));
}
Пример #14
0
static void event_exit()
{
  char msg[512];
  int len;
  len = snprintf(msg, sizeof(msg) / sizeof(msg[0]), "Number of basi blocks built : %"UINT64_FORMAT_CODE"\n"
  "    Average size        : %5.2lf instructions\n",
  counts_as_built.blocks, counts_as_built.total_size / (double)counts_as_built.blocks);
  DR_ASSERT(len > 0);
  msg[sizeof(msg)/sizeof(msg[0])-1] = '\0'; /*NULL Terminate */
  DISPLAY_STRING(msg);

  /* Free mutex */
  dr_mutex_destroy(as_built_lock);
}
Пример #15
0
void memtrace_init(client_id_t id,const char * name, const char * arguments)
{

	char logfilename[MAX_STRING_LENGTH];
	file_t in_file;


	drmgr_init();
    drutil_init();

    client_id = id;
    mutex = dr_mutex_create();

	DR_ASSERT(parse_commandline_args(arguments) == true);
	
	head = md_initialize();


	if(client_arg->filter_mode != FILTER_NONE){
		in_file = dr_open_file(client_arg->filter_filename,DR_FILE_READ);
		DR_ASSERT(in_file != INVALID_FILE);
		md_read_from_file(head,in_file,false);
		dr_close_file(in_file);
	}
    
    tls_index = drmgr_register_tls_field();
    DR_ASSERT(tls_index != -1);

    code_cache_init();

	if (log_mode){
		populate_conv_filename(logfilename, logdir, name, NULL);
		logfile = dr_open_file(logfilename, DR_FILE_WRITE_OVERWRITE);
	}
	strncpy(ins_pass_name, name, MAX_STRING_LENGTH);

}
Пример #16
0
static instr_t * static_info_instrumentation(void * drcontext, instr_t* instr){
	/*
		for each src and dest add the information accordingly
		this should return canonicalized static info about an instruction; breaking down any complex instructions if necessary

		1) check whether this instruction needs to be instrumented
		2) if yes, then get a location and then proceed to instrument -> return the struct
		3) if no, return null

	*/

	/* main variables */
	per_thread_t * data = drmgr_get_tls_field(drcontext,tls_index);

	/* helper variables */
	int opcode;
	instr_t * ret;
	
	/* loop variables */
	int i;

	/* 1) */

	opcode = instr_get_opcode(instr);

	if (client_arg->instrace_mode == OPCODE_TRACE){
		opcodes_visited[opcode] = true;
		return NULL;
	}

	if ( (client_arg->instrace_mode == OPERAND_TRACE) || (client_arg->instrace_mode == INS_DISASM_TRACE) ){
		operand_trace(instr, drcontext);
		return NULL;
	}

	/* check whether this instr needs instrumentation - check for ones to skip and skip if */
	/*switch(opcode){
	case OP_jecxz:
		return NULL;
	}*/
	
	/* 2) */

	data->static_array[data->static_ptr++] = instr_clone(drcontext,instr);
	DR_ASSERT(data->static_ptr < data->static_array_size);

	return data->static_array[data->static_ptr - 1];

}
Пример #17
0
DR_EXPORT void 
dr_init(client_id_t id)
{
    /* register events */
    dr_register_thread_init_event(event_thread_init);
    dr_register_thread_exit_event(event_thread_exit);
    dr_register_exit_event(event_exit);
    dr_register_bb_event(event_basic_block);
    /* The TLS field provided by DR cannot be directly accessed from code cache.
     * For better performance, we allocate raw TLS so that we can directly
     * access and update it with a single instruction.
     */
    if(!dr_raw_tls_calloc(&tls_seg, &tls_offs, 1, 0))
        DR_ASSERT(false);
}
Пример #18
0
void
writeCallgrind(int thread_id){
	char logname[MAXIMUM_PATH];
	char *dirsep;
    	int len;
	char * tmp = process_path;

	len = dr_snprintf(logname, sizeof(logname)/sizeof(logname[0]),
                      "%s", tmp);

	DR_ASSERT(len > 0);
	for (dirsep = logname + len; *dirsep != '/'; dirsep--)
        DR_ASSERT(dirsep > logname);
    	len = dr_snprintf(dirsep + 1,
                      (sizeof(logname) - (dirsep - logname))/sizeof(logname[0]),
                      "callgrind.%d.out", thread_id);
    	DR_ASSERT(len > 0);
    	NULL_TERMINATE(logname);
    	logOut = dr_open_file(logname, 
                             DR_FILE_WRITE_OVERWRITE | DR_FILE_ALLOW_LARGE);
    	DR_ASSERT(logOut != INVALID_FILE);
//    	dr_log(drcontext, LOG_ALL, 1, 
 //          "floating point: log for thread %d is fp.%03d\n",thread_id, thread_id);
	#ifdef SHOW_RESULTS
    	if (dr_is_notify_on()) {
//        	dr_fprintf(STDERR, "<floating point instruction operands for thread %d in %s>\n",
//                  dr_get_thread_id(drcontext), logname);
    	}
	#endif	

       	dr_fprintf(logOut, "version: 1\n");
       	dr_fprintf(logOut, "creator: callgrind-3.6.1-Debian\n");
       	dr_fprintf(logOut, "positions: instr line\n");
       	dr_fprintf(logOut, "events: Average Max\n\n\n");

}
Пример #19
0
static void
wrap_post(void *wrapcxt, void *user_data)
{
#ifdef SHOW_RESULTS /* we want determinism in our test suite */
    size_t sz = (size_t) user_data;
    /* test out-of-memory by having a random moderately-large alloc fail */
    if (sz > 1024 && dr_get_random_value(1000) < 10) {
        bool ok = drwrap_set_retval(wrapcxt, NULL);
        DR_ASSERT(ok);
        dr_mutex_lock(max_lock);
        malloc_oom++;
        dr_mutex_unlock(max_lock);
    }
#endif
}
Пример #20
0
DR_EXPORT void
dr_init(client_id_t id)
{
    drreg_options_t ops = { sizeof(ops), 2 /*max slots needed*/, false };
    drreg_status_t res;
    bool ok = drmgr_init();
    CHECK(ok, "drmgr_init failed");
    ok = drx_init();
    CHECK(ok, "drx_init failed");
    res = drreg_init(&ops);
    CHECK(res == DRREG_SUCCESS, "drreg_init failed");
    dr_register_exit_event(event_exit);
    if (!drmgr_register_bb_instrumentation_event(NULL, event_app_instruction, NULL))
        DR_ASSERT(false);
}
Пример #21
0
static void do_mem_dump(file_t file, uint base_pc,uint size){

	uint read;
	bool ok;
	byte * mem_values = dr_global_alloc(sizeof(byte) * size);
	ssize_t written;

	ok = dr_safe_read(base_pc, size, mem_values, &read);
	DR_ASSERT(ok);
	written = dr_write_file(file, mem_values, size);
	DEBUG_PRINT("read %d from %x of size %d and written %d\n", read, base_pc, size, written);

	dr_global_free(mem_values, sizeof(byte) * size);

}
Пример #22
0
/*
 * Helper function for bulk use of drwrap.
 */
static void try_wrap_fn(const module_data_t *module, const char *name,
                        prewrapper_t pre, postwrapper_t post, bool *done)
{
    if (*done)
        return;

    size_t offset;
    drsym_error_t status = drsym_lookup_symbol(
        module->full_path, name, &offset, DRSYM_DEFAULT_FLAGS);
    if (status == DRSYM_SUCCESS) {
        app_pc notify_fn = module->start + offset;
        bool ok = drwrap_wrap(notify_fn, pre, post);
        DR_ASSERT(ok);
        *done = true;
    }
}
Пример #23
0
static void
show_results(void)
{
#ifdef SHOW_RESULTS
    char msg[512];
    int len;
    /* Note that using %f with dr_printf or dr_fprintf on Windows will print
     * garbage as they use ntdll._vsnprintf, so we must use dr_snprintf.
     */
    len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                      "<Number of system calls seen: %d>", num_syscalls);
    DR_ASSERT(len > 0);
    msg[sizeof(msg)/sizeof(msg[0])-1] = '\0';
    DISPLAY_STRING(msg);
#endif /* SHOW_RESULTS */
}
Пример #24
0
trace_type_t
offline_instru_t::get_entry_type(byte *buf_ptr) const
{
    offline_entry_t *entry = (offline_entry_t *) buf_ptr;
    switch (entry->addr.type) {
    case OFFLINE_TYPE_MEMREF: return TRACE_TYPE_READ;
    case OFFLINE_TYPE_MEMREF_HIGH: return TRACE_TYPE_READ;
    case OFFLINE_TYPE_PC: return TRACE_TYPE_INSTR;
    case OFFLINE_TYPE_THREAD: return TRACE_TYPE_THREAD;
    case OFFLINE_TYPE_PID: return TRACE_TYPE_PID;
    case OFFLINE_TYPE_TIMESTAMP: return TRACE_TYPE_THREAD; // Closest.
    case OFFLINE_TYPE_IFLUSH: return TRACE_TYPE_INSTR_FLUSH;
    }
    DR_ASSERT(false);
    return TRACE_TYPE_THREAD_EXIT; // Unknown: returning rarest entry.
}
Пример #25
0
static void
event_exit(void)
{
    if (!drmgr_unregister_tls_field(tls_idx) ||
        !drmgr_unregister_thread_init_event(event_thread_init) ||
        !drmgr_unregister_thread_exit_event(event_thread_exit) ||
        !drmgr_unregister_bb_app2app_event(event_bb_app2app) ||
        !drmgr_unregister_bb_insertion_event(event_app_instruction))
        DR_ASSERT(false);

    drx_buf_free(write_buffer);
    drx_buf_free(trace_buffer);
    drutil_exit();
    drreg_exit();
    drmgr_exit();
    drx_exit();
}
Пример #26
0
static void 
event_exit(void)
{
#ifdef SHOW_RESULTS
    char msg[256];
    int len;
    len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                      "<Largest malloc request: %d>\n<OOM simulations: %d>\n",
                      max_malloc, malloc_oom);
    DR_ASSERT(len > 0);
    NULL_TERMINATE(msg);
    DISPLAY_STRING(msg);
#endif /* SHOW_RESULTS */

    dr_mutex_destroy(max_lock);
    drwrap_exit();
}
Пример #27
0
static inline void
ordered_lock(ipc_channel_t *channel, uint tid)
{
    dr_mutex_lock(channel->queue_lock);

    ticket_queue_t *q = &channel->ticket_queue;
    if (q->locked)
    {
        ticket_node_t *node = dr_global_alloc(sizeof(ticket_node_t));
        if (node == NULL)
            DR_ABORT_MSG("Failed to allocate ticket node\n");
        node->next = NULL;
        node->dr_event = dr_event_create();
        node->waiting = true;
        node->thread_id = tid;

        DR_ASSERT(q->tail->next == NULL);
        q->tail = q->tail->next = node;

        SGL_DEBUG("Sleeping Thread :%d\n", tid);
        dr_mutex_unlock(channel->queue_lock);

        /* MDL20170425 TODO(soonish)
         * how likely is it that we'll miss a wakeup here? */
        while (node->waiting)
            dr_event_wait(node->dr_event);

        dr_mutex_lock(channel->queue_lock);

        q->head->next = node->next;
        if (q->tail == node)
            q->tail = q->head;

        dr_event_destroy(node->dr_event);
        dr_global_free(node, sizeof(ticket_node_t));

        SGL_DEBUG("Awakened Thread :%d\n", tid);
    }
    else
    {
        q->locked = true;
    }

    dr_mutex_unlock(channel->queue_lock);
}
Пример #28
0
/* save reg before where in ilist */
void
umbra_save_reg(void         *drcontext,
               umbra_info_t *info,
               instrlist_t  *ilist,
               instr_t      *where,
               reg_id_t      reg)
{
    int slot;
    instr_t *instr;

    DR_ASSERT(reg >= REG_SPILL_START && reg <= REG_SPILL_STOP);
    slot  = reg - REG_SPILL_START;
    instr = INSTR_CREATE_mov_st(drcontext,
                                OPND_CREATE_ABSMEM(&info->spill_regs[slot],
                                        OPSZ_PTR),
                                opnd_create_reg(reg));
    instrlist_meta_preinsert(ilist, where, instr);
}
Пример #29
0
static void
display_results(per_thread_t *data, char *thread_note)
{
#ifdef SHOW_RESULTS
    char msg[512];
    int len;
    len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                      "%sInstrumentation results:\n"
                      "  saw %d direct calls\n"
                      "  saw %d indirect calls\n"
                      "  saw %d returns\n",
                      thread_note, data->num_direct_calls,
                      data->num_indirect_calls, data->num_returns);
    DR_ASSERT(len > 0);
    NULL_TERMINATE(msg);
    DISPLAY_STRING(msg);
#endif /* SHOW_RESULTS */
}
Пример #30
0
static void 
event_thread_exit(void *drcontext)
{
    per_thread_t *data = (per_thread_t *) dr_get_tls_field(drcontext);
    char msg[512];
    int len;

    len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                      "Thread %d exited - ", dr_get_thread_id(drcontext));
    DR_ASSERT(len > 0);
    NULL_TERMINATE(msg);

    /* display thread private counts data */
    display_results(data, msg);

    /* clean up memory */
    dr_thread_free(drcontext, data, sizeof(per_thread_t));
}