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);
}

Reply via email to