[Libevent-users] evdns: How to quite event-loop

Tassilo von Parseval tassilo.von.parseval at rwth-aachen.de
Mon Nov 6 03:13:17 EST 2006


On Nov 5, 2006, at 6:57 PM, Nick Mathewson wrote:

> On Sun, Nov 05, 2006 at 09:54:41AM +0000, Tassilo von Parseval wrote:
>  [...]
>>             I called either evdns_clear_nameservers_and_suspend
>> or evdns_shutdown, both to no avail: the first would segfault while
>> the second tickled an assertion.
>>
>> How can I make sure that an application doesn't get stuck in the
>> mainloop when using libevent's DNS lookups?
>
> Hi, Tassilo!  Segfaults and assertions are usually not intended
> behavior; can you provide stack traces for either?

Alright, here we are. The following little program:

==>
#include <sys/types.h>
#include <stdio.h>
#include <evdns.h>

static char *hosts[] = { "www.google.com", "www.heise.de",  
"www.bbc.co.uk" };

int global_count;

void
check_exit (void) {
     extern int global_count;
     if (global_count == 0)
         evdns_clear_nameservers_and_suspend();
}

void
callback (int result, char type, int count, int ttl, void *addr, char  
*host) {
     uint32_t *packed;
     extern int global_count;
     int i;

     global_count--;

     if (!count) {
         printf("Couldn't resolve %s\n", host);
         check_exit();
         return;
     }

     printf("%s is:\n", host);
     for (i = 0; i < count; ++i) {
         int oct[4];
         packed = (uint32_t*)addr;
         oct[0] = (packed[i] & 0x000000ff);
         oct[1] = (packed[i] & 0x0000ff00)>>8;
         oct[2] = (packed[i] & 0x00ff0000)>>16;
         oct[3] = (packed[i] & 0xff000000)>>24;
         printf("\t%i.%i.%i.%i\n", oct[0], oct[1], oct[2], oct[3]);
     }
     check_exit();
     return;
}

int main (int argc, char **argv) {
     int i;
     extern int global_count;

     event_init();
     evdns_init();

     for (i = 0; i < sizeof(hosts)/sizeof(*hosts); ++i) {
         evdns_resolve_ipv4(hosts[i], 0, (evdns_callback_type) 
callback, hosts[i]);
         global_count++;
     }

     return event_dispatch();
}
<==

Compilation and running under gdb gives:
$ gcc -DDNS_USE_GETTIMEOFDAY_FOR_ID -g -Ilibevent-1.2/ - 
Llibevent-1.2/.libs/ -levent ev.c -o resolve
$ gdb resolve
GNU gdb 6.1-20040303 (Apple version gdb-437) (Fri Jan 13 18:45:48 GMT  
2006)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and  
you are
welcome to change it and/or distribute copies of it under certain  
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for  
details.
This GDB was configured as "i386-apple-darwin"...Reading symbols for  
shared libraries ... done

(gdb) r
Starting program: /Users/ethan/resolve
Reading symbols for shared libraries .+ done
www.google.com is:
         64.233.183.104
www.heise.de is:
         193.99.144.85
www.bbc.co.uk is:
         212.58.226.232

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x000000c0
nameserver_up (ns=0x0) at evdns.c:438
438     evdns.c: No such file or directory.
         in evdns.c
(gdb) bt
#0  nameserver_up (ns=0x0) at evdns.c:438
#1  0x00036db4 in reply_handle (req=0x300500, flags=0, ttl=205,  
reply=0xbffff6c0) at evdns.c:628
#2  0x00037385 in nameserver_ready_callback (fd=10, events=2,  
arg=0x3001b0) at evdns.c:780
#3  0x00030e56 in event_base_loop (base=0x300120, flags=0) at event.c: 
309
#4  0x00031016 in event_loop (flags=0) at event.c:358
#5  0x0003102e in event_dispatch () at event.c:321
#6  0x00001f46 in main (argc=1, argv=0xbffffa30) at ev.c:56

When I change evdns_clear_nameservers_and_suspend() to evdns_shutdown 
(0), this happens:

(gdb) r
Starting program: /Users/ethan/resolve
Reading symbols for shared libraries .+ done
www.heise.de is:
         193.99.144.85
www.bbc.co.uk is:
         212.58.226.232
www.google.com is:
         64.233.183.147
         64.233.183.103
         64.233.183.104
         64.233.183.99
resolve(5560) malloc: ***  Deallocation of a pointer not malloced:  
0x3002d0; This could be a double free(), or free() called with the  
middle of an allocated block; Try setting environment variable  
MallocHelp to see tools to help debug
evdns.c:398: failed assertion `global_good_nameservers >= 0'

Program received signal SIGABRT, Aborted.
0x9003d1dc in kill ()
(gdb) bt
#0  0x9003d1dc in kill ()
#1  0x9010f2af in raise ()
#2  0x9010de02 in abort ()
#3  0x0003913f in __eprintf ()
#4  0x0003517c in nameserver_failed (ns=0x3001b0, msg=0x9015ee00 "Bad  
file descriptor") at evdns.c:398
#5  0x000373ab in nameserver_ready_callback (fd=10, events=2,  
arg=0x3001b0) at evdns.c:879
#6  0x00030e56 in event_base_loop (base=0x300120, flags=0) at event.c: 
309
#7  0x00031016 in event_loop (flags=0) at event.c:358
#8  0x0003102e in event_dispatch () at event.c:321
#9  0x00001f49 in main (argc=1, argv=0xbffffa30) at ev.c:56


Please let me know if you need more details.

Cheers,
Tassilo



More information about the Libevent-users mailing list