More and better support for tasks. Add anal.sleep to avoid 100% cpu in analysis

This commit is contained in:
pancake 2014-11-02 02:01:09 +01:00
parent 6a6290a4da
commit 1e3e97f2fb
7 changed files with 47 additions and 15 deletions

View File

@ -219,6 +219,8 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
int adjust;
int un_idx; // delay.un_idx
} delay = {0};
if (anal->sleep)
r_sys_usleep (anal->sleep);
if (depth<1) {
return R_ANAL_RET_ERROR; // MUST BE TOO DEEP

View File

@ -630,8 +630,8 @@ static int taskbgrun(RThread *th) {
char *res = r_core_cmd_str (core, task->msg->text);
task->msg->res = res;
eprintf ("Task %d finished\n", task->id);
return 0;
// TODO: run callback and pass result
return 0;
}
static int cmd_thread(void *data, const char *input) {
@ -653,7 +653,7 @@ static int cmd_thread(void *data, const char *input) {
if (tid) {
RCoreTask *task = r_core_task_get (core, tid);
if (task) {
//r_core_task_join (core, task);
r_core_task_join (core, task);
} else eprintf ("Cannot find task\n");
} else {
r_core_task_run (core, NULL);
@ -665,8 +665,10 @@ static int cmd_thread(void *data, const char *input) {
if (tid) {
RCoreTask *task = r_core_task_get (core, tid);
if (task) {
r_cons_printf ("Task %d Status %c\n", task->id, task->state);
r_cons_printf ("%s\n", task->msg->text);
r_cons_printf ("Task %d Status %c Command %s\n",
task->id, task->state, task->msg->text);
if (task->msg->res)
r_cons_printf ("%s\n", task->msg->res);
} else eprintf ("Cannot find task\n");
} else {
r_core_task_list (core, 1);
@ -687,6 +689,8 @@ static int cmd_thread(void *data, const char *input) {
const char* help_msg[] = {
"Usage:", "&[-|<cmd>]", "Manage tasks",
"&", "", "list all running threads",
"&=", "", "show output of all tasks",
"&=", " 3", "show output of task 3",
"&j", "", "list all running threads (in JSON)",
"&?", "", "show this help",
"&+", " aa", "push to the task list",
@ -697,6 +701,7 @@ static int cmd_thread(void *data, const char *input) {
"&&", "", "run all pendings tasks (and join threads)",
"&&&", "", "run all pendings tasks until ^C",
"","","TODO: last command should honor asm.bits",
"","","WARN: this feature is very experimental. Use it with caution",
NULL};
// TODO: integrate with =h& and bg anal/string/searchs/..
r_core_cmd_help (core, help_msg);
@ -704,11 +709,20 @@ static int cmd_thread(void *data, const char *input) {
break;
case ' ':
{
RCoreTask *task = r_core_task_add (core, r_core_task_new (core, input+1, (RCoreTaskCallback)task_finished, core));
RThread *th = r_th_new (taskbgrun, task, 0);
task->msg->th = th;
//r_core_cmd0 (core, task->msg->text);
//r_core_task_del (core, task->id);
int tid = r_num_math (core->num, input+1);
if (tid) {
RCoreTask *task = r_core_task_get (core, tid);
if (task) {
r_core_task_join (core, task);
} else eprintf ("Cannot find task\n");
} else {
RCoreTask *task = r_core_task_add (core, r_core_task_new (
core, input+1, (RCoreTaskCallback)task_finished, core));
RThread *th = r_th_new (taskbgrun, task, 0);
task->msg->th = th;
}
//r_core_cmd0 (core, task->msg->text);
//r_core_task_del (core, task->id);
}
break;
default:

View File

@ -72,6 +72,14 @@ static int cb_analeobjmp(void *user, void *data) {
core->anal->eobjmp = node->i_value;
return R_TRUE;
}
static int cb_analsleep(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->sleep = node->i_value;
return R_TRUE;
}
static int cb_analnopskip (void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
@ -794,6 +802,7 @@ R_API int r_core_config_init(RCore *core) {
/* anal */
SETCB("anal.eobjmp", "true", &cb_analeobjmp, "jmp is end of block mode (option)");
SETI("anal.depth", 16, "Max depth at code analysis"); // XXX: warn if depth is > 50 .. can be problematic
SETICB("anal.sleep", 0, &cb_analsleep, "Sleep some usecs before analyzing more. Avoid 100% cpu usage");
SETPREF("anal.hasnext", "true", "Continue analysis after each function");
SETPREF("anal.esil", "false", "Use the new ESIL code analysis");
SETCB("anal.nopskip", "false", &cb_analnopskip, "Skip nops at the begining of functions");

View File

@ -817,7 +817,7 @@ R_API RCore *r_core_fini(RCore *c) {
if (!c) return NULL;
/* TODO: it leaks as shit */
//update_sdb (c);
r_core_task_join (c);
r_core_task_join (c, NULL);
free (c->cmdqueue);
free (c->lastcmd);
r_io_free (c->io);

View File

@ -13,7 +13,8 @@ R_API void r_core_task_list (RCore *core, int mode) {
task->id, task->state, task->msg->text, iter->n?",":"");
break;
default:
r_cons_printf ("%d %c %s\n", task->id, task->state, task->msg->text);
r_cons_printf ("Task %d Status %c Command %s\n",
task->id, task->state, task->msg->text);
if (mode == 1) {
r_cons_printf ("%s", task->msg->res);
}
@ -23,11 +24,16 @@ R_API void r_core_task_list (RCore *core, int mode) {
if (mode=='j') r_cons_printf("]\n");
}
R_API void r_core_task_join (RCore *core) {
RCoreTask *task;
R_API void r_core_task_join (RCore *core, RCoreTask *task) {
RListIter *iter;
r_list_foreach_prev (core->tasks, iter, task) {
if( task) {
r_cons_break (NULL, NULL);
r_th_wait (task->msg->th);
r_cons_break_end ();
} else {
r_list_foreach_prev (core->tasks, iter, task) {
r_th_wait (task->msg->th);
}
}
}

View File

@ -527,6 +527,7 @@ typedef struct r_anal_t {
int lineswidth; // wtf
int big_endian;
int split; // used only from core
int sleep; // sleep some usecs before analyzing more (avoid 100% cpu usages)
int nopskip; // skip nops at the begining of functions
void *user;
RList *fcns;

View File

@ -478,7 +478,7 @@ R_API void r_core_task_run_bg(RCore *core, RCoreTask *_task);
R_API RCoreTask *r_core_task_add (RCore *core, RCoreTask *task);
R_API void r_core_task_add_bg (RCore *core, RCoreTask *task);
R_API int r_core_task_del (RCore *core, int id);
R_API void r_core_task_join (RCore *core);
R_API void r_core_task_join (RCore *core, RCoreTask *task);
/* PLUGINS */
extern RCorePlugin r_core_plugin_java;