I'm trying compile program using function gethostbyname() with the cross compiler arm-none-linux-gnueabi, but it did not work when I run my binary on android.
My code in below:
/* gethostbyname-example.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
extern int h_errno;
int main(int argc,char **argv) {
int x, x2;
struct hostent *hp;
for ( x=1; x<argc; ++x ) {
hp = gethostbyname(argv[x]);
if ( !hp ) {
fprintf(stderr,
"%s: host '%s'\n",
hstrerror(h_errno),
argv[x]);
continue;
}
printf("Host %s : \n" ,argv[x]);
printf(" Officially:\t%s\n", hp->h_name);
fputs(" Aliases:\t",stdout);
for ( x2=0; hp->h_aliases[x2]; ++x2 ) {
if ( x2 ) {
fputs(", ",stdout);
}
fputs(hp->h_aliases[x2],stdout);
}
fputc('\n',stdout);
printf(" Type:\t\t%s\n",
hp->h_addrtype == AF_INET
? "AF_INET" : "AF_INET6");
if ( hp->h_addrtype == AF_INET ) {
for ( x2=0; hp->h_addr_list[x2]; ++x2 ) {
printf(" Address:\t%s\n",
inet_ntoa( *(struct in_addr *)
hp->h_addr_list[x2]));
}
}
putchar('\n');
}
return 0;
}
I compile with arm-none-linux-gnueabi-gcc, On my laptop with OS ubuntu 12.04 and cross compiler Sourcery Codebench:
$ arm-none-linux-gnueabi-gcc gethostbyname-example.c --static -o gethostbyname-example
/tmp/ccE0xjBG.o: In function `main':
lookup.c:(.text+0x38): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ls
gethostbyname-example.c gethostbyname-example
$ file gethostbyname-example
gethostbyname-example: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
And then I test the binary gethostbyname-example on my chroot arm, I copy-paste the binary to chroot folder and then I login to chroot, and I execute, BTW I make chroot from here https://wiki.ubuntu.com/ARM/BuildEABIChroot , if I run it on chroot I get result as below:
# ./gethostbyname-example www.google.com
Host google.com :
Officially: www.google.com
Aliases:
Type: AF_INET
Address: 74.125.135.139
Address: 74.125.135.100
Address: 74.125.135.101
Address: 74.125.135.102
Address: 74.125.135.113
Address: 74.125.135.138
Then also I upload binary gethostbyname-example with adb push to my android device, and if I run the binary gethostbyname-example I get error as below:
# ./gethostbyname-example www.google.com # Unknown server error: host 'www.google.com' # ping www.google.com # PING www.google.com (74.125.135.99) 56(84) bytes of data. # 64 bytes from ni-in-f99.1e100.net (74.125.135.99): icmp_seq=1 ttl=49 time=798 ms # 64 bytes from ni-in-f99.1e100.net (74.125.135.99): icmp_seq=2 ttl=49 time=1039 ms
In my android device I have a file hosts in /etc/ and /system/etc/ with google DNS
8.8.8.8
8.8.4.4
Approximately what the cause of this failure,
Thank you.
DNS lookup in glibc requires /lib/libnss_dns.so.2 , which is not available on Android.
Another difference is that Android stores the DNS settings /system/etc/resolv.conf , and native Android apps built with the bionic C library will look there to find the DNS servers to query. Applications built with glibc will look in /etc/resolv.conf , which doesn't exist on Android.
You've built the binaries using glibc, while Android uses the bionic C library.
This should for the most part be fine when linking to a libc statically, as I'm not aware of severe enough changes in the android kernel to break simple user land apps. You're supposed to use the Android NDK for building android native apps though,
There's however a few things that goes wrong when linking to glibc statically. Certain functions in glibc, e.g. for looking up user info, host names and other things that's normally configured in /etc/nsswitch.conf calls out to other shared libraries to actually do the work. This happens regardless of whether you link to glibc itself statically or not. These files are usually the /lib/libnss_* files found on glibc systems.
Most of those shared libraries are part of glibc, and would be installed on glibc systems. But they're not available on Android. Applications relying the funcions that uses these helper shared libs not work properly when these shared libraries are available - gethostbyname() is one of them, as for normal DNS queries it requres /lib/libnss_dns.so.2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With