Bug 1331 - libunbound segfault in threaded mode when context is deleted
libunbound segfault in threaded mode when context is deleted
Status: RESOLVED FIXED
Product: unbound
Classification: Unclassified
Component: server
1.6.4
Other All
: P5 normal
Assigned To: unbound team
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2017-07-03 13:31 CEST by Andrew Tunnell-Jones
Modified: 2017-07-03 13:45 CEST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Tunnell-Jones 2017-07-03 13:31:14 CEST
Hi,

If I create a context, set async to true, start an asynchronous resolve and then delete the context I seem to be able to reliably raise a segfault.

    #include <unbound.h>

    static void callback(void* arg, int err, struct ub_result* result) {}

    int main(void) {
        struct ub_ctx* ctx = ub_ctx_create();
        ub_ctx_async(ctx, 1);
        ub_resolve_async(ctx, "example.com.", 1, 1, 0, callback, 0);
        ub_ctx_delete(ctx);
    }

I get the same result on macOS with 1.6.4 and Debian with 1.4.22. On the Mac, if I insert a ten second sleep before calling ub_ctx_delete no segfault occurs. I haven't tried that on Debian. Both machines are wimpy, the Mac is a dual-core with hyper-threading and the Debian machine is a $3 single-core VPS.

Look forward to your advice,

Andrew
Comment 1 Wouter Wijngaards 2017-07-03 13:45:46 CEST
Hi Andrew,

Thank you for the bug report.  I have fixed the bug.  The fix is in the code repository, but the patch is also here should you want it.

Best regards, Wouter

Index: libunbound/libworker.c
===================================================================
--- libunbound/libworker.c	(revision 4256)
+++ libunbound/libworker.c	(working copy)
@@ -749,7 +749,7 @@
 {
 	struct ctx_query* q = (struct ctx_query*)arg;
 
-	if(q->cancelled) {
+	if(q->cancelled || q->w->back->want_to_quit) {
 		if(q->w->is_bg_thread) {
 			/* delete it now */
 			struct ub_ctx* ctx = q->w->ctx;