Esempio n. 1
0
void stack_trace (MonoMethod *method, void *args[], ArmRegs *regs) {
    LOGD ("stack_trace be call!");
    MonoContext ctx;
    ctx.eip = regs->pc;
    ctx.esp = regs->sp;
    ctx.ebp = regs->r11;
    memcpy (ctx.regs, regs, 4 * 16);
    MemWriter writer;
    /*因为当前被跟踪的函数还没被调用(当前在specific_trampo中), 所以这里手动写入当前函数的跟踪结构*/
    char const *m = get_method_image_name (method);
    m = m ? m : "NO_IMAGE_NAME";
    char const *n = mono_method_full_name (method, 1);
    if (n) {
        writer.sprintf ("[%s]%s[%08X]\n", m, n, mono_method_get_token (method));
        g_free (n);
    } else {
        writer.sprintf ("[%s]%s[%08X]\n", m, "NO_METHOD_NAME", mono_method_get_token (method));
    }
    mono_walk_stack (mono_domain_get (), 0, &ctx, walk_stack, &writer);

    xmono::StackTraceRsp rsp;
    rsp.set_err (true);
    rsp.set_stack (std::string ((char*)writer.getBuffPtr (), writer.getBuffSize ()));
    std::string out;
    rsp.SerializeToString (&out);
    ecmd_send (XMONO_ID_STACK_TRACE_RSP, (uint8_t const*)out.c_str (), out.size ());
}
Esempio n. 2
0
static int walk_stack (MonoDomain *domain, MonoContext *ctx, MonoJitInfo *jit_info, void *user_data) {
    MemWriter *writer = (MemWriter*)user_data;
    MonoMethod *method =mono_jit_info_get_method (jit_info);
    if (!method) {
        writer->sprintf("%s", "jit_info no method!");
        return 0;
    }
    char const *m = get_method_image_name (method);
    m = m ? m : "NO_IMAGE_NAME";
    char const *n = mono_method_full_name (method, 1);
    if (n) {
        writer->sprintf ("[%s] %s [%08X]\n", m, n, mono_method_get_token (method));
        g_free (n);
    } else {
        writer->sprintf ("[%s] %s [%08X]\n", m, "NO_METHOD_NAME", mono_method_get_token (method));
    }
    return 0; /*一直walk, 直到栈帧尽头*/
}
Esempio n. 3
0
static void
foreach_method (gpointer data, gpointer user_data)
{
	ForeachData *udata = (ForeachData*)user_data;
	MonoMethod *method = (MonoMethod*)data;
	char *name;

	if (!mono_method_get_token (method) || mono_class_get_image (mono_method_get_class (method)) != udata->image)
		return;

	name = mono_method_full_name (method, TRUE);
	fprintf (udata->outfile, "%s\n", name);
	g_free (name);
}
Esempio n. 4
0
/*监控需要hook的函数*/
static void profile_jit_result (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result) {
    if (result == MONO_PROFILE_FAILED) return;
    if (mono_method_get_token (method) == 0) return;                /*一般是动态生成的marshall*/
    uint32_t iflags;
    int flag = mono_method_get_flags (method, &iflags);
    if (iflags != 0) return;                                        /*iflags非0 一般是一些native和特殊的method实现*/
    if (mono_jit_info_get_code_size (jinfo) < 4) return;            /*代码段太小, 无法hook*/

    void *p = mono_jit_info_get_code_start (jinfo);
    if (p == 0) {
        LOGD ("function code size is null");
        return;
    }

        /*测试jit函数是否是mov r12, sp*/
    if (*(uint32_t*)p != 0xE1A0C00D)
         LOGD ("exception func : %s , %p", mono_method_get_name (method), p);

    /*TODO : 增加可配置的image和函数列表*/
    if (strcmp (get_method_image_name (method), "Assembly-CSharp") != 0) return;
    if (strcmp (mono_method_get_name (method), ".ctor") == 0) return;
    if (strcmp (mono_method_get_name (method), ".cctor") == 0) return;
    if (strcmp (mono_method_get_name (method), "set") == 0) return;
    if (strcmp (mono_method_get_name (method), "get") == 0) return;
    if (strcmp (mono_method_get_name (method), "Update") == 0) return;
    if (strcmp (mono_method_get_name (method), "LateUpdate") == 0) return;
    if (strcmp (mono_method_get_name (method), "OnGUI") == 0) return;

    /*TODO : 需要一个容器来存储还未编译, 但又想hook的函数*/

    bool donthook = false;
    pthread_mutex_lock (&replace_mutex);
    if (replace_method_dict.find (method) != replace_method_dict.end ())
        donthook = true;
    pthread_mutex_unlock (&replace_mutex);
    if (donthook) return;

    char *hook = specific_hook (p, method, (void*)func_trace);
    if (hook == 0) {
        /*将失败的hook也放到一个表里面*/
        LOGD ("hook err : %s", mono_method_get_name (method));
        return;
    }
    pthread_mutex_lock (&hooked_mutex);
    hooked_method_dict[method] = new HookInfo(jinfo, hook);
    pthread_mutex_unlock (&hooked_mutex);
    LOGD ("hook func : %s , %p", mono_method_get_name (method), p);
    return;
}
Esempio n. 5
0
MonoDebugMethodInfo *
mono_debug_symfile_lookup_method (MonoDebugHandle *handle, MonoMethod *method)
{
    MonoSymbolFileMethodEntry *first_ie, *ie;
    MonoDebugMethodInfo *minfo;
    MonoSymbolFile *symfile = handle->symfile;

    if (!symfile->method_hash)
        return NULL;

    if (handle->image != mono_class_get_image (mono_method_get_class (method)))
        return NULL;

    mono_debugger_lock ();

    minfo = g_hash_table_lookup (symfile->method_hash, method);
    if (minfo) {
        mono_debugger_unlock ();
        return minfo;
    }

    first_ie = (MonoSymbolFileMethodEntry *)
               (symfile->raw_contents + read32(&(symfile->offset_table->_method_table_offset)));

    ie = bsearch (GUINT_TO_POINTER (mono_method_get_token (method)), first_ie,
                  read32(&(symfile->offset_table->_method_count)),
                  sizeof (MonoSymbolFileMethodEntry), compare_method);

    if (!ie) {
        mono_debugger_unlock ();
        return NULL;
    }

    minfo = g_new0 (MonoDebugMethodInfo, 1);
    minfo->index = (ie - first_ie) + 1;
    minfo->method = method;
    minfo->handle = handle;

    minfo->data_offset = read32 (&(ie->_data_offset));
    minfo->lnt_offset = read32 (&(ie->_line_number_table));

    g_hash_table_insert (symfile->method_hash, method, minfo);

    mono_debugger_unlock ();
    return minfo;
}
Esempio n. 6
0
static void send_trace_log (std::map<MonoMethod*, CallInfo> const &dict) {
    MemWriter sbuf(0x100000);
    MemWriter writer(0x100000);
    std::map<MonoMethod*, CallInfo>::const_iterator p;
    for (p = dict.begin (); p != dict.end (); p++) {
        MonoMethod *method = p->first;
        CallInfo call_info = p->second;
        char const *m = get_method_image_name (method);
        char *n = mono_method_full_name (method, 0);
        char str[256];
        sbuf.sprintf ("[%s] %s [%08X]|%d|%d\n", m, n, mono_method_get_token (method), call_info.times, call_info.order);
        g_free (n);
    }
    if (!compress_data (sbuf.getBuffPtr (), sbuf.getBuffSize (), &writer)) {
        LOGD ("compress_data err!");
        return;
    }
    /*Fixme : 这里写在使用protocolbuf之前, 因此非常不河蟹的出现了不使用pb的封包*/
    ecmd_send (XMONO_ID_TRACE_REPORT, writer.getBuffPtr (), writer.getBuffSize ());
    return;
}
Esempio n. 7
0
static void
output_method (MonoMethod *method, gpointer dummy, MonoProfiler *prof)
{
	MonoMethodHeader *header;
	char *classname;
	char *tmpsig;
	char *tmpname;
	FILE *outfile;
	MonoClass *klass;
	MonoImage *image;

	outfile = prof->outfile;
	header = mono_method_get_header (method);

	tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
	tmpsig = g_markup_escape_text (tmpsig, strlen (tmpsig));

	klass = mono_method_get_class (method);
	classname = mono_type_get_name (mono_class_get_type (klass));
	image = mono_class_get_image (klass);

	tmpname = mono_method_get_name (method);
	tmpname = g_markup_escape_text (tmpname, strlen (tmpname));

	fprintf (outfile, "\t<method assembly=\"%s\" class=\"%s\" name=\"%s (%s)\" token=\"%d\">\n",
			 mono_image_get_name (image),
			 classname, tmpname,
			 tmpsig, mono_method_get_token (method));

	g_free (tmpsig);
	g_free (tmpname);
	fprintf (outfile, "\t\t");
	count = 0;
	prev_offset = 0;

	mono_profiler_coverage_get (prof, method, output_entry);

	fprintf (outfile, "\n");
	fprintf (outfile, "\t</method>\n");
}
Esempio n. 8
0
static void disasm_method (Package *pkg) {
    xmono::DisasmMethodReq req;
    xmono::DisasmMethodRsp rsp;
    std::string str((char*)pkg->body, pkg->all_len - sizeof (Package)); //Fixme : 修复头部all_len是总长的问题
    if (!req.ParseFromString (str)) {
        LOGD ("xmono::DisasmMethodReq ParseFromString err!");
        return;
    }
    std::string err("");
    MonoMethod *method = get_method_with_token (req.image_name ().c_str (), req.method_token ());
    if (!method) err += helper_last_err ();
    MonoImage *image = mono_image_loaded (req.image_name ().c_str ());
    if (!image) err += "  image : " + req.image_name () + " can not be find!";
    if (image && method) {
        MemWriter writer(4096);
        char const *mname = mono_method_full_name (method, 1);
        if (mname) {
            writer.sprintf ("//[%s]%s[%08X]\n", get_method_image_name (method), mname, mono_method_get_token (method));
            g_free (mname);
        }
        MonoMethodHeader *header = mono_method_get_header (method);
        disassemble_cil (image, header, &writer); /*Fixme : disassemble_cil需要在失败时返回更多信息*/
        rsp.set_err (true);
        LOGD ("writer : %s", writer.getBuffPtr ());
        std::string s((char*)writer.getBuffPtr (), writer.getBuffSize ());
        rsp.set_disasm_code (s);
        //这部分只是测试用的
        uint32_t asm_size = 0;
        uint8_t const *p = mono_method_header_get_code (header, &asm_size, 0);
        std::string asm_code ((char const*)p, asm_size);
        rsp.set_asm_code (asm_code);
    } else {
        rsp.set_err (false);
        rsp.set_err_str (err);
    }
    std::string out;
    rsp.SerializeToString (&out);
    ecmd_send (XMONO_ID_DISASM_METHOD_RSP, (uint8_t const*)out.c_str (), out.size ());
    return;
}