From e505ea74b63394100f47233295f0a1835ffb99c2 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 14 Oct 2018 15:54:04 +0200 Subject: Refined measures of elapsed time. --- plugins/devdbg/speed.c | 187 ++++++++++++++++++++++++++++++++++++------ plugins/devdbg/speed.h | 3 + plugins/pychrysalide/plugin.c | 10 +++ src/format/format.c | 8 ++ src/plugins/pglist.h | 3 + src/plugins/plugin-def.h | 20 ++++- src/plugins/plugin-int.h | 4 + src/plugins/plugin.c | 33 ++++++++ src/plugins/plugin.h | 3 + 9 files changed, 243 insertions(+), 28 deletions(-) diff --git a/plugins/devdbg/speed.c b/plugins/devdbg/speed.c index f9fccfe..935fbd9 100644 --- a/plugins/devdbg/speed.c +++ b/plugins/devdbg/speed.c @@ -24,39 +24,46 @@ #include "speed.h" +#include #include -#include +#include #include -#include +#include + + +#include #include DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("Speed Measure", "Tracks to time spent for disassembling code", "0.1.0", + PGA_FORMAT_ANALYSIS_STARTED,PGA_FORMAT_ANALYSIS_ENDED, + PGA_FORMAT_POST_ANALYSIS_STARTED, PGA_FORMAT_POST_ANALYSIS_ENDED, PGA_DISASSEMBLY_STARTED, PGA_DISASSEMBLY_ENDED); /* Mémorisation des résultats de chronométrages */ typedef struct _speed_measure { - clock_t points[2]; /* Points de mesure successifs */ unsigned long usages[2]; /* Taux d'utilisation du CPU */ } speed_measure; +/* Affiche une mesure de temps écoulé. */ +static void show_elapsed_time(const GPluginModule *, const char *, const speed_measure *); + + /****************************************************************************** * * * Paramètres : plugin = greffon à manipuler. * -* action = type d'action attendue. * -* binary = binaire dont le contenu est en cours de traitement.* -* status = barre de statut à tenir informée. * -* context = contexte de désassemblage. * +* title = désignation humaine de la mesure menée. * +* measure = mesure de temps écoulé. * * * -* Description : Exécute une action pendant un désassemblage de binaire. * +* Description : Affiche une mesure de temps écoulé. * * * * Retour : - * * * @@ -64,23 +71,158 @@ typedef struct _speed_measure * * ******************************************************************************/ -G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, PluginAction action, GLoadedBinary *binary, GtkStatusStack *status, GProcContext *context) +static void show_elapsed_time(const GPluginModule *plugin, const char *title, const speed_measure *measure) +{ + char *tmp; /* Construction temporaire */ + double seconds; /* Secondes écoulées */ + unsigned long minutes; /* Minutes écoulées */ + unsigned long hours; /* Heures écoulées */ + char *msg; /* Message à faire passer */ + + tmp = NULL; + + seconds = (double)(measure->usages[1] - measure->usages[0]) / 1000000; + + if (seconds > 60) + { + minutes = seconds / 60; + seconds -= minutes * 60; + } + else + minutes = 0; + + if (minutes > 60) + { + hours = minutes / 60; + minutes %= 60; + } + else + hours = 0; + + msg = strdup(title); + + if (hours > 0) + { + asprintf(&tmp, " %lu", hours); + msg = stradd(msg, tmp); + free(tmp); + + msg = stradd(msg, _("h")); + + } + + if (minutes > 0) + { + asprintf(&tmp, " %lu", minutes); + msg = stradd(msg, tmp); + free(tmp); + + msg = stradd(msg, _("m")); + + } + + if (seconds > 0.01) + { + asprintf(&tmp, " %.2f", seconds); + msg = stradd(msg, tmp); + free(tmp); + + msg = stradd(msg, _("s")); + + } + + if (tmp != NULL) + g_plugin_module_log_simple_message(plugin, LMT_INFO, msg); + + free(msg); + +} + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* format = format de binaire à manipuler pendant l'opération. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * +* * +* Description : Procède à une opération liée à l'analyse d'un format. * +* * +* Retour : Bilan de l'exécution du traitement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +G_MODULE_EXPORT bool handle_binary_format_analysis(const GPluginModule *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status) { speed_measure *measure; /* Suivi des progressions */ + struct timeval point; /* Point de mesure courant */ - void take_measure(clock_t *point, unsigned long *usage) + switch (action) { - struct rusage rusage; /* Notification des usages */ + case PGA_FORMAT_ANALYSIS_STARTED: + case PGA_FORMAT_POST_ANALYSIS_STARTED: + + measure = (speed_measure *)calloc(1, sizeof(speed_measure)); + g_object_set_data(G_OBJECT(format), "speed_measure", measure); + + gettimeofday(&point, NULL); + measure->usages[0] = point.tv_sec * 1000000 + point.tv_usec; + + break; + + case PGA_FORMAT_ANALYSIS_ENDED: + case PGA_FORMAT_POST_ANALYSIS_ENDED: - *point = clock(); + measure = (speed_measure *)g_object_get_data(G_OBJECT(format), "speed_measure"); - getrusage(RUSAGE_THREAD, &rusage); + gettimeofday(&point, NULL); + measure->usages[1] = point.tv_sec * 1000000 + point.tv_usec; - *usage = rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec; - *usage += rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec; + if (action == PGA_FORMAT_ANALYSIS_ENDED) + show_elapsed_time(plugin, _("Whole elapsed time for format analysis:"), measure); + else + show_elapsed_time(plugin, _("Whole elapsed time for format post-analysis:"), measure); + + g_object_set_data(G_OBJECT(format), "speed_measure", NULL); + free(measure); + + break; + + default: + assert(false); + break; } + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* binary = binaire dont le contenu est en cours de traitement.* +* status = barre de statut à tenir informée. * +* context = contexte de désassemblage. * +* * +* Description : Exécute une action pendant un désassemblage de binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, PluginAction action, GLoadedBinary *binary, GtkStatusStack *status, GProcContext *context) +{ + speed_measure *measure; /* Suivi des progressions */ + struct timeval point; /* Point de mesure courant */ + switch (action) { case PGA_DISASSEMBLY_STARTED: @@ -88,23 +230,19 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, Plu measure = (speed_measure *)calloc(1, sizeof(speed_measure)); g_object_set_data(G_OBJECT(binary), "speed_measure", measure); - take_measure(&measure->points[0], &measure->usages[0]); + gettimeofday(&point, NULL); + measure->usages[0] = point.tv_sec * 1000000 + point.tv_usec; break; - case PGA_DISASSEMBLY_ENDED: measure = (speed_measure *)g_object_get_data(G_OBJECT(binary), "speed_measure"); - take_measure(&measure->points[1], &measure->usages[1]); - -#define SHOW_SPEED(pg, sm, title, p0, p1) \ - g_plugin_module_log_variadic_message(pg, LMT_INFO, title ": %.2g (%.2g)", \ - (double)(sm->points[p1] - sm->points[p0]) / CLOCKS_PER_SEC, \ - (sm->usages[p1] - sm->usages[p0]) / 1000000.0); + gettimeofday(&point, NULL); + measure->usages[1] = point.tv_sec * 1000000 + point.tv_usec; - SHOW_SPEED(plugin, measure, "Whole elapsed time for disassembly", 0, 1); + show_elapsed_time(plugin, _("Whole elapsed time for disassembly:"), measure); g_object_set_data(G_OBJECT(binary), "speed_measure", NULL); free(measure); @@ -112,6 +250,7 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, Plu break; default: + assert(false); break; } diff --git a/plugins/devdbg/speed.h b/plugins/devdbg/speed.h index 4367570..e99d81c 100644 --- a/plugins/devdbg/speed.h +++ b/plugins/devdbg/speed.h @@ -30,6 +30,9 @@ +/* Procède à une opération liée à l'analyse d'un format. */ +G_MODULE_EXPORT bool handle_binary_format_analysis(const GPluginModule *, PluginAction, GBinFormat *, wgroup_id_t, GtkStatusStack *); + /* Exécute une action pendant un désassemblage de binaire. */ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *, PluginAction , GLoadedBinary *, GtkStatusStack *, GProcContext *); diff --git a/plugins/pychrysalide/plugin.c b/plugins/pychrysalide/plugin.c index eb6d00d..e57ffaf 100644 --- a/plugins/pychrysalide/plugin.c +++ b/plugins/pychrysalide/plugin.c @@ -747,11 +747,21 @@ static bool py_plugin_module_define_constants(PyTypeObject *obj_type) result = true; result &= PyDict_AddIntMacro(obj_type, PGA_BASIC_NONE); + result &= PyDict_AddIntMacro(obj_type, PGA_PLUGIN_INIT); result &= PyDict_AddIntMacro(obj_type, PGA_PLUGIN_EXIT); + result &= PyDict_AddIntMacro(obj_type, PGA_CONTENT_EXPLORER); result &= PyDict_AddIntMacro(obj_type, PGA_CONTENT_RESOLVER); + result &= PyDict_AddIntMacro(obj_type, PGA_CONTENT_ANALYZED); + + result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_ANALYSIS_STARTED); + result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_PRELOAD); result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_LOADER_LAST); + result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_ANALYSIS_ENDED); + result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_POST_ANALYSIS_STARTED); + result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_POST_ANALYSIS_ENDED); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_STARTED); result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_RAW); result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_HOOKED_LINK); diff --git a/src/format/format.c b/src/format/format.c index ac6b215..de57e4c 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -326,10 +326,14 @@ bool g_binary_format_analyze(GBinFormat *format, wgroup_id_t gid, GtkStatusStack bool result; /* Bilan à retourner */ GBinFormatClass *class; /* Classe de l'instance */ + handle_binary_format_analysis(PGA_FORMAT_ANALYSIS_STARTED, format, gid, status); + class = G_BIN_FORMAT_GET_CLASS(format); result = class->analyze(format, gid, status); + handle_binary_format_analysis(PGA_FORMAT_ANALYSIS_ENDED, format, gid, status); + return result; } @@ -470,11 +474,15 @@ void g_binary_format_complete_analysis(GBinFormat *format, wgroup_id_t gid, GtkS { GBinFormatClass *class; /* Classe de l'instance */ + handle_binary_format_analysis(PGA_FORMAT_POST_ANALYSIS_STARTED, format, gid, status); + class = G_BIN_FORMAT_GET_CLASS(format); if (class->complete != NULL) class->complete(format, gid, status); + handle_binary_format_analysis(PGA_FORMAT_POST_ANALYSIS_ENDED, format, gid, status); + } diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h index 7cc4416..5fc2867 100644 --- a/src/plugins/pglist.h +++ b/src/plugins/pglist.h @@ -98,6 +98,9 @@ GPluginModule **get_all_plugins_for_action(PluginAction, size_t *); /* DPS_FORMAT */ +#define handle_binary_format_analysis(a, f, g, s) \ + process_all_plugins_for(a, g_plugin_module_handle_binary_format_analysis, f, g, s) + #define handle_binary_format(a, f, s) \ process_all_plugins_for(a, g_plugin_module_handle_binary_format, f, s) diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h index 643b6e2..f404b14 100644 --- a/src/plugins/plugin-def.h +++ b/src/plugins/plugin-def.h @@ -130,11 +130,23 @@ typedef enum _PluginAction * DPC_BINARY_PROCESSING | DPS_FORMAT */ - /* Accompagnement du chargement (fin) */ - PGA_FORMAT_LOADER_LAST = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(0), + /* Début de l'analyse d'un format */ + PGA_FORMAT_ANALYSIS_STARTED = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(0), - /* Accompagnement du chargement (fin) */ - PGA_FORMAT_PRELOAD = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(1), + /* Accompagnement du chargement */ + PGA_FORMAT_PRELOAD = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(1), + + /* Accompagnement du chargement */ + PGA_FORMAT_LOADER_LAST = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(2), + + /* Fin de l'analyse d'un format */ + PGA_FORMAT_ANALYSIS_ENDED = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(3), + + /* Début de la vague finale d'analyse d'un format */ + PGA_FORMAT_POST_ANALYSIS_STARTED = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(4), + + /* Début de la vague finale d'analyse d'un format */ + PGA_FORMAT_POST_ANALYSIS_ENDED = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(5), /** * DPC_BINARY_PROCESSING | DPS_DISASSEMBLY diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h index d04d9ab..0ab4f56 100644 --- a/src/plugins/plugin-int.h +++ b/src/plugins/plugin-int.h @@ -53,6 +53,9 @@ typedef void (* pg_handle_content_fc) (const GPluginModule *, PluginAction, GBin /* Procède à une opération liée à un contenu chargé. */ typedef void (* pg_handle_loaded_fc) (const GPluginModule *, PluginAction, GLoadedContent *, wgroup_id_t, GtkStatusStack *); +/* Assure l'interprétation d'un format en différé. */ +typedef bool (* pg_handle_format_analysis_fc) (const GPluginModule *, PluginAction, GBinFormat *, wgroup_id_t, GtkStatusStack *); + /* Procède à une opération liée au format de fichier uniquement. */ typedef bool (* pg_handle_format_fc) (const GPluginModule *, PluginAction, GBinFormat *, GtkStatusStack *); @@ -124,6 +127,7 @@ struct _GPluginModule pg_handle_content_fc handle_content; /* Explorations ou résolutions */ pg_handle_loaded_fc handle_loaded; /* Traitement de contenu chargé*/ + pg_handle_format_analysis_fc handle_fmt_analysis; /* Analyse de format */ pg_handle_format_fc handle_format; /* Manipulation du format */ pg_preload_format_fc preload_format; /* Préchargement d'un format */ diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 40f44ce..b63b263 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -334,6 +334,16 @@ GPluginModule *g_plugin_module_new(const gchar *filename) switch (action) { + case PGA_FORMAT_ANALYSIS_STARTED: + case PGA_FORMAT_ANALYSIS_ENDED: + case PGA_FORMAT_POST_ANALYSIS_STARTED: + case PGA_FORMAT_POST_ANALYSIS_ENDED: + if (!load_plugin_symbol(result->module, + "handle_binary_format_analysis", + &result->handle_fmt_analysis)) + goto bad_plugin; + break; + case PGA_FORMAT_LOADER_LAST: if (!load_plugin_symbol(result->module, "handle_binary_format", &result->handle_format)) @@ -781,6 +791,29 @@ void g_plugin_module_handle_loaded_content(const GPluginModule *plugin, PluginAc * Paramètres : plugin = greffon à manipuler. * * action = type d'action attendue. * * format = format de binaire à manipuler pendant l'opération. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * +* * +* Description : Procède à une opération liée à l'analyse d'un format. * +* * +* Retour : Bilan de l'exécution du traitement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_plugin_module_handle_binary_format_analysis(const GPluginModule *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + return plugin->handle_fmt_analysis(plugin, action, format, gid, status); + +} + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* format = format de binaire à manipuler pendant l'opération. * * status = barre de statut à tenir informée. * * * * Description : Procède à une opération liée au format de fichier uniquement.* diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h index a73cc6f..718531a 100644 --- a/src/plugins/plugin.h +++ b/src/plugins/plugin.h @@ -97,6 +97,9 @@ void g_plugin_module_handle_binary_content(const GPluginModule *, PluginAction, /* Procède à une opération liée à un contenu chargé. */ void g_plugin_module_handle_loaded_content(const GPluginModule *, PluginAction, GLoadedContent *, wgroup_id_t, GtkStatusStack *); +/* Procède à une opération liée à l'analyse d'un format. */ +bool g_plugin_module_handle_binary_format_analysis(const GPluginModule *, PluginAction, GBinFormat *, wgroup_id_t, GtkStatusStack *); + /* Procède à une opération liée au format de fichier uniquement. */ bool g_plugin_module_handle_binary_format(const GPluginModule *, PluginAction, GBinFormat *, GtkStatusStack *); -- cgit v0.11.2-87-g4458