Hi folks,
In the attached file, I delete a uv_work_t after running uv_queue_work,
which causes a use-after-free crash. This is somewhat surprising behavior.
1. The documentation does not make it clear that the uv_work_t passed to
uv_queue_work needs to remain alive until (presumably?) the callbacks have
all completed, which leads to:
2. Since uv_queue_work spins off another thread to do the work, and since
this may happen in a context where you're spinning many uv_work_t tasks off
to run simultaneously, it's not clear where the uv_work_t should be
deleted. Declaring it on the stack of the caller of uv_run isn't a very
good solution because you can't stack-declare arbitrary numbers of
uv_work_t, which you need to do if you're potentially queuing lots of
background work at once. Allocating it on the heap, meanwhile, brings up
the question of (A) is user code responsible for deleting the uv_work_t, or
is libuv? and (B) if user code is responsible, when is it safe to delete
the work_t? During the "done" callback?
-William
--
You received this message because you are subscribed to the Google Groups
"libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
void fake_download(uv_work_t* w) {
int size = *((int*) w->data);
printf("fake_download: data is %d\n", size);
}
void after(uv_work_t* w, int unused) {
int size = *((int*) w->data);
printf("after: data is %d\n", size);
}
int main() {
uv_loop_t* loop = uv_default_loop();
uv_work_t* req = (uv_work_t*) malloc(sizeof(uv_work_t));
int size = 123456;
req->data = (void*) &size;
uv_queue_work(loop, req, fake_download, after);
free(req);
return uv_run(loop, UV_RUN_DEFAULT);
}