Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

HELP on How to configure DynamoRIO drcov to periodically flush the log file

25 views
Skip to first unread message

张德通

unread,
Dec 19, 2024, 10:11:54 AM12/19/24
to DynamoRIO Users
Dear DR friends,
How could i control how often data is written to the log file, rather than only writing at the end of the program. This is because my service is an online service, and I do not have the authority to perform start and stop operations.

I've created a simple example using dr_set_itimer, but I've encountered some problems.

(1) If I call the drcovlib_dump function within the timer callback function, the log file will keep increasing in size. Suppose the size of the log file is X after the normal program ends. Now, after each call to the drcovlib_dump function, the size of the log file will become 1X, 2X, 3X...
(2) Later, I tried to execute drcovlib_exit first and then drcovlib_init within the callback function. I found that different log files, such as 0000.proc.log and 0001.proc.log, would be generated after each timing. This is in line with the expected situation. However, when the timed callback is executed for the second time, the drcovlib_init function will crash, my code like below ,in dr_client_main function,drcovlib_init was SUCCESS, in the first coverage_flush_callback, exit_status and init_status was SUCCESS, but in the second coverage_flush_callback, exit_status was SUCCESS, drcovlib_init was crashed...


static void coverage_flush_callback(void *drcontext, void *timer_id, int interval) {

drcovlib_status_t exit_status, init_status; exit_status = drcovlib_exit(); dr_fprintf(STDERR, "drcovlib_exit returned: %d\n", exit_status); if (exit_status != DRCOVLIB_SUCCESS) { dr_fprintf(STDERR, "Failed to exit and dump coverage data.\n"); return; } else { dr_fprintf(STDERR, "Coverage data dumped successfully.\n"); } drcovlib_options_t cov_opts; memset(&cov_opts, 0, sizeof(drcovlib_options_t)); cov_opts.struct_size = sizeof(drcovlib_options_t); cov_opts.logdir = "/tmp"; if (!drcovlib_init(&cov_opts)) { dr_fprintf(STDERR, "Failed to initialize drcovlib.\n"); return; } else { dr_fprintf(STDERR, "drcovlib initialized successfully.\n"); }

}

DR_EXPORT void dr_client_main(client_id_t client_id, int argc, const char *argv[]) {

drcovlib_options_t cov_opts; memset(&cov_opts, 0, sizeof(drcovlib_options_t)); cov_opts.struct_size = sizeof(drcovlib_options_t); cov_opts.logdir = "/tmp"; if (!drcovlib_init(&cov_opts)) { dr_fprintf(STDERR, "Failed to initialize drcovlib.\n"); return; } else { dr_fprintf(STDERR, "drcovlib initialized successfully.\n"); } dr_set_itimer(ITIMER_REAL, 60000, coverage_flush_callback);

}

Abhinav Sharma

unread,
Dec 20, 2024, 10:37:19 AM12/20/24
to DynamoRIO Users
Hi,

>  However, when the timed callback is executed for the second time, the drcovlib_init function will crash

As noted in the documentation of drcovlib_init[1], it "Must be called prior to any of the other routines". Your second call to drcovlib_init violates that requirement, hence the crash.

> How could i control how often data is written to the log file, rather than only writing at the end of the program.

I don't think periodic dumps are supported today by drcovlib. It may be useful to have this feature. Could you please file a feature request at https://github.com/DynamoRIO/dynamorio/issues/new?template=feature_request.md?

We probably need a new drcovlib API that allows the user to register a callback_user that will be invoked every X ms.

Based on a quick look at drcovlib, a possible implementation strategy is: drcovlib can register its own callback_drcovlib using dr_set_itimer. drcovlib can have two separate instances of the bb_table in its per_thread_t data[2], one for bb_table_total and the other for bb_table_since_last_callback. Then at each invocation of callback_drcovlib, callback_user can be invoked with bb_table_since_last_callback, and bb_table_since_last_callback can be merged into bb_table_total (so that the overall data can still be dumped at the end).

We welcome contributions from the community and would appreciate if you're willing to work on this.


Thanks,
Abhinav

Abhinav Sharma

unread,
Dec 20, 2024, 9:57:40 PM12/20/24
to DynamoRIO Users
> Your second call to drcovlib_init violates that requirement, hence the crash.

I should clarify that we don't know the precise reason why the second call to drcovlib_init crashes. Calling exit and init in an itimer callback repeatedly is not an explicitly supported usage model and I can imagine various things going wrong. E.g.:
- There could parts of drcovlib_init that may not re-initialize correctly on the second call.
- If your application is multi-threaded, one thread may do drcovlib_exit and de-allocate data structures while other threads are still using them

Maybe it's a good idea to get a stack trace for that second drcovlib_init crash to know precisely what's happening.

> This is because my service is an online service, and I do not have the authority to perform start and stop operations.

Curious about this: do you mean your service is launched and run throughout under DynamoRIO?

Abhinav



Derek Bruening

unread,
Dec 22, 2024, 12:16:05 PM12/22/24
to DynamoRIO Users
I believe the author here already filed https://github.com/DynamoRIO/dynamorio/issues/7153 to which I had added references to two other past users list threads wanting the same thing, including one with a partial patch.
Reply all
Reply to author
Forward
0 new messages