--------------
 Each probe argument follows below syntax.
 
- [NAME=]LOCALVAR|$retval|%REG|@SYMBOL
+ [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
 
 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
+'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo.
 
 LINE SYNTAX
 -----------
 
 }
 
 /* Parse perf-probe event argument */
-static void parse_perf_probe_arg(const char *str, struct perf_probe_arg *arg)
+static void parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
 {
        char *tmp;
        struct perf_probe_arg_field **fieldp;
        tmp = strchr(str, '=');
        if (tmp) {
                arg->name = xstrndup(str, tmp - str);
+               pr_debug("name:%s ", arg->name);
                str = tmp + 1;
        }
 
+       tmp = strchr(str, ':');
+       if (tmp) {      /* Type setting */
+               *tmp = '\0';
+               arg->type = xstrdup(tmp + 1);
+               pr_debug("type:%s ", arg->type);
+       }
+
        tmp = strpbrk(str, "-.");
        if (!is_c_varname(str) || !tmp) {
                /* A variable, register, symbol or special value */
                len -= ret;
                field = field->next;
        }
+
+       if (pa->type) {
+               ret = e_snprintf(tmp, len, ":%s", pa->type);
+               if (ret <= 0)
+                       goto error;
+               tmp += ret;
+               len -= ret;
+       }
+
        return tmp - buf;
 error:
        die("Failed to synthesize perf probe argument: %s", strerror(-ret));
                        free(pev->args[i].name);
                if (pev->args[i].var)
                        free(pev->args[i].var);
+               if (pev->args[i].type)
+                       free(pev->args[i].type);
                field = pev->args[i].field;
                while (field) {
                        next = field->next;
                        if (pev->args[i].name)
                                tev->args[i].name = xstrdup(pev->args[i].name);
                        tev->args[i].value = xstrdup(pev->args[i].var);
+                       if (pev->args[i].type)
+                               tev->args[i].type = xstrdup(pev->args[i].type);
                }
        }
 
 
                                        &die_mem);
                vr_die = &die_mem;
        }
-       convert_variable_type(vr_die, pf->tvar);
+       if (pf->pvar->type)
+               pf->tvar->type = xstrdup(pf->pvar->type);
+       else
+               convert_variable_type(vr_die, pf->tvar);
        /* *expr will be cached in libdw. Don't free it. */
        return ;
 error:
 static void find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
        Dwarf_Die vr_die;
-       char buf[32];
+       char buf[32], *ptr;
 
        /* TODO: Support arrays */
        if (pf->pvar->name)
                pf->tvar->name = xstrdup(pf->pvar->name);
        else {
                synthesize_perf_probe_arg(pf->pvar, buf, 32);
+               ptr = strchr(buf, ':'); /* Change type separator to _ */
+               if (ptr)
+                       *ptr = '_';
                pf->tvar->name = xstrdup(buf);
        }