I have a program which requires a DNS query and a sqlite3 DB connection.
I have determined that it hangs indefinitely at a getaddrinfo()
call. So I created a test program (from busybox's nslookup.c
) with only this call. When I do not link the libsqlite3
it works as expected. The code segment is as follows:
#include <arpa/inet.h>
#include <netdb.h>
#include <resolv.h>
#include <string.h>
#include <signal.h>
static int sockaddr_to_dotted(struct sockaddr *saddr, char *buf, int buflen)
{
if (buflen <= 0) return -1;
buf[0] = '\0';
if (saddr->sa_family == AF_INET)
{
inet_ntop(AF_INET, &((struct sockaddr_in*)saddr)->sin_addr, buf, buflen);
return 0;
}
if (saddr->sa_family == AF_INET6)
{
inet_ntop(AF_INET6, &((struct sockaddr_in6*)saddr)->sin6_addr, buf, buflen);
return 0;
}
return -1;
}
static int print_host(const char *hostname, const char *header)
{
char str[128]; /* IPv6 address will fit, hostnames hopefully too */
struct addrinfo *result = NULL;
int rc;
struct addrinfo hint;
memset(&hint, 0, sizeof(hint));
/* hint.ai_family = AF_UNSPEC; - zero anyway */
/* Needed. Or else we will get each address thrice (or more)
* for each possible socket type (tcp,udp,raw...): */
hint.ai_socktype = SOCK_STREAM;
// hint.ai_flags = AI_CANONNAME;
printf("BEFORE GETADDRINFO\n");
rc = getaddrinfo(hostname, NULL /*service*/, &hint, &result);
printf("AFTER GETADDRINFO\n");
if (!rc)
{
struct addrinfo *cur = result;
// printf("%s\n", cur->ai_canonname); ?
while (cur)
{
sockaddr_to_dotted(cur->ai_addr, str, sizeof(str));
printf("%s %s\nAddress: %s\n", header, hostname, str);
str[0] = ' ';
if (getnameinfo(cur->ai_addr, cur->ai_addrlen, str + 1,
sizeof(str) - 1, NULL, 0, NI_NAMEREQD))
str[0] = '\0';
puts(str);
cur = cur->ai_next;
}
}
else
{
printf("getaddrinfo('%s') failed: %s", hostname, gai_strerror(rc));
}
freeaddrinfo(result);
return (rc != 0);
}
int main(int argc, char **argv)
{
if (argc != 2)
return -1;
res_init();
return print_host(argv[1], "Name: ");
}
I can only see "BEFORE GETADDRINFO" on the output. I also tried to strace the program. (My dns server is 192.168.11.11, and queried "www.google.com") This is where it suspends:
socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.11.11")}, 16) = 0
send(3, "\0\2\1\0\0\1\0\0\0\0\0\0\3www\6google\3com\0\0\1\0\1", 32, 0) = 32
pselect6(4, [3], NULL, NULL, {10, 0}, 0) = 1 (in [3], left {9, 988000000})
recv(3, "\0\2\201\200\0\1\0\5\0\0\0\0\3www\6google\3com\0\0\1\0"..., 512, 0) = 112
close(3) = 0
rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
rt_sigsuspend([]
My compiler is bfin-linux-uclibc-gcc
(gcc version 4.1.2)
I cross compiled sqlite3 for bfin-linux-uclibc
(version 3.6.23)
I appreciate any comment, help, debug procedure suggestion.
output of strace -e trace=file mybinary
:
stat("/etc/ld.so.cache", {st_mode=S_IFREG|0644, st_size=1073, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/libsqlite3.so.0", O_RDONLY) = 3
open("/lib/libstdc++.so.6", O_RDONLY) = 3
open("/lib/libm.so.0", O_RDONLY) = 3
open("/lib/libgcc_s.so.1", O_RDONLY) = 3
open("/lib/libc.so.0", O_RDONLY) = 3
open("/lib/libdl.so.0", O_RDONLY) = 3
open("/lib/libpthread.so.0", O_RDONLY) = 3
open("/lib/libgcc_s.so.1", O_RDONLY) = 3
open("/lib/libc.so.0", O_RDONLY) = 3
open("/lib/libm.so.0", O_RDONLY) = 3
open("/lib/libgcc_s.so.1", O_RDONLY) = 3
open("/lib/libc.so.0", O_RDONLY) = 3
open("/lib/libc.so.0", O_RDONLY) = 3
open("/lib/libc.so.0", O_RDONLY) = 3
open("/lib/libc.so.0", O_RDONLY) = 3
open("/lib/libc.so.0", O_RDONLY) = 3
stat("/lib/ld-uClibc.so.0", {st_mode=S_IFREG|0755, st_size=29824, ...}) = 0
open("/etc/resolv.conf", O_RDONLY) = 3
open("/etc/hosts", O_RDONLY) = 3
Output of bfin-linux-uclibc-nm -g mybinary
00004fc4 A ___bss_start
w ___deregister_frame_info@@GCC_3.0
00004f10 D ___dso_handle
00004fc4 A __edata
00004fe0 A __end
00000d60 T __fini
U _freeaddrinfo
U _gai_strerror
U _getaddrinfo
U _getnameinfo
U _inet_ntop
00000534 T __init
w __Jv_RegisterClasses
00000aa4 T _main
U _printf
U _puts
w ___register_frame_info@@GCC_3.0
U ___res_init
00000e18 R __ROFIXUP_END__
00000de0 R __ROFIXUP_LIST__
00000670 T ___self_reloc
00020000 A __stacksize
0000060c T __start
U ___uClibc_main