Android - 在recvfrom()上一致地接收分段错误

时间:2014-04-28 13:36:53

标签: android c android-ndk segmentation-fault recvfrom

我在BScEE的最后一个项目我试图创建一个ad-hoc网络。 我正在使用Galaxy S2设备并用C(JNI)编写大部分代码。 除了发送普通信息外,我还会每5秒自动发送一次广播。 有一个线程正在监听并等待接收数据。 由于分段错误我一直崩溃 - 使用ndk-stack和addr2line它指向我recvfrom: int retval = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen); 我有一个想法是,因为大多数时候有一个线程在运行并等待接收,它的误报和分段问题在其他地方。

如何调试分段错误的原因,以及它实际上是由recvfrom()代码引起的。 [我可以在这里添加墓碑,如果有帮助的话]

编辑1:fadden墓碑是2700行长,我添加了开始和结束。最后包含我们的应用程序,它指示我回收。

墓碑的开头:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'samsung/GT-I9100/GT-I9100:2.3.5/GINGERBREAD/XXKI4:user/release-keys'
pid: 4309, tid: 4309  >>> com.example.adhocktest <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
r0 00000027  r1 deadbaad  r2 a0000000  r3 00000000
r4 00000001  r5 00000000  r6 00285068  r7 0000a000
r8 00000000  r9 00000014  10 44295df4  fp 802a6374
ip afd466a8  sp bef83210  lr afd196f1  pc afd161c0  cpsr 60000030
d0  4224000043040000  d1  0000002842ba0000
d2  42ba000000000000  d3  0000000000000000
d4  8000000000000000  d5  429800003f800000
d6  00000000c2980000  d7  4110000043040000
d8  3e59364e3d8f5c29  d9  0000002643da8000
d10 0000000042180000  d11 0000000000000000
d12 0000000000000000  d13 0000000000000000
d14 0000000000000000  d15 0000000000000000
d16 c053000000000000  d17 c053000000000000
d18 0000000000000000  d19 0000000000000000
d20 3ff0000000000000  d21 8000000000000000
d22 0000000000000000  d23 0000000000000000
d24 0000000000000000  d25 4071600000000000
d26 4030000000000000  d27 3ff0000000000000
d28 3aa680003a854000  d29 3ff0000000000000
d30 0000000000000000  d31 3ff0000000000000
scr 20000010

     #00  pc 000161c0  /system/lib/libc.so
     #01  pc 00013b30  /system/lib/libc.so
     #02  pc 000149f6  /system/lib/libc.so
     #03  pc 0001a9ea  /system/lib/libutils.so
     #04  pc 0001dc26  /system/lib/libutils.so
     #05  pc 0001dd56  /system/lib/libutils.so
     #06  pc 0001dda2  /system/lib/libutils.so
     #07  pc 000220d8  /system/lib/libutils.so
     #08  pc 00022298  /system/lib/libutils.so
     #09  pc 0005129c  /system/lib/libandroid_runtime.so
     #10  pc 000512a6  /system/lib/libandroid_runtime.so
     #11  pc 00017ef4  /system/lib/libdvm.so
     #12  pc 000498f4  /system/lib/libdvm.so
     #13  pc 0001d108  /system/lib/libdvm.so
     #14  pc 000221a8  /system/lib/libdvm.so
     #15  pc 00021098  /system/lib/libdvm.so
     #16  pc 00060266  /system/lib/libdvm.so
     #17  pc 0006803a  /system/lib/libdvm.so
     #18  pc 0001d108  /system/lib/libdvm.so
     #19  pc 000221a8  /system/lib/libdvm.so
     #20  pc 00021098  /system/lib/libdvm.so
     #21  pc 000600c8  /system/lib/libdvm.so
     #22  pc 0004c3c2  /system/lib/libdvm.so
     #23  pc 0003c316  /system/lib/libandroid_runtime.so
     #24  pc 0003dcaa  /system/lib/libandroid_runtime.so
     #25  pc 00008cca  /system/bin/app_process
     #26  pc 0001506e  /system/lib/libc.so

墓碑结束:

--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
pid: 4309, tid: 4345   Thread-12

r0 fffffe00  r1 002a2bd0  r2 000000c8  r3 00000000
r4 4a0b6b44  r5 4a0b6b30  r6 0000005b  r7 00000124
r8 4a0b6b70  r9 47012fb0  10 47012f98  fp 802a6374
ip 4a0b6b10  sp 4a0b6b00  lr 813027d3  pc afd0c1e4  cpsr 40000010
d0  4140000041a80000  d1  3ff0000041ac0000
d2  4d852dc0424ac9e8  d3  42c8000000540ff0
d4  bf800000002a9e00  d5  0000000000000000
d6  3f80000000000000  d7  4030000000000000
d8  0000000000000000  d9  0000000000000000
d10 0000000000000000  d11 0000000000000000
d12 0000000000000000  d13 0000000000000000
d14 0000000000000000  d15 0000000000000000
d16 000000000005f007  d17 0000800000008000
d18 ffd4cb1affd52334  d19 ffa54dd2ffa604a4
d20 ffffa7e6ffffa7e6  d21 ffff492effff492e
d22 0001c5a20001c5a2  d23 000166e9000166e9
d24 0000000200000002  d25 0000000000000000
d26 0000000000000000  d27 0000000000000000
d28 0000000000000000  d29 0000000000000000
d30 0000000000000000  d31 0000000000000000
scr 20000010

     #00  pc 0000c1e4  /system/lib/libc.so
     #01  pc 000027d0  /data/data/com.example.adhocktest/lib/libadhoc-jni.so
     #02  pc 00017ef4  /system/lib/libdvm.so
     #03  pc 000498f4  /system/lib/libdvm.so
     #04  pc 0001d108  /system/lib/libdvm.so
     #05  pc 000221a8  /system/lib/libdvm.so
     #06  pc 00021098  /system/lib/libdvm.so
     #07  pc 000600c8  /system/lib/libdvm.so
     #08  pc 000602dc  /system/lib/libdvm.so
     #09  pc 0005462a  /system/lib/libdvm.so
     #10  pc 00011e00  /system/lib/libc.so
     #11  pc 000119cc  /system/lib/libc.so

这是接收JNI功能:

jstring
Java_com_example_adhocktest_ReceiverUDP_RecvUdpJNI(JNIEnv* env1,
    jobject thiz)
    {
int PORT = 8888;
int BUFLEN = 10240;
int retVal=-1;
int is_ignore_msg = 0;
int is_forward_msg = 0;

__android_log_write(ANDROID_LOG_INFO, "RecvUdpJNI()",  "Entering RecvUdpJNI"); // TODO: Remove

struct sockaddr_in my_addr, cli_addr;
int sockfd, i;
socklen_t slen=sizeof(cli_addr);
char* buf;
char* strstrptr;
buf = (char*)malloc(BUFLEN*sizeof(char));
if (buf == NULL) {
    __android_log_print(ANDROID_LOG_INFO, "NetworkMap","RecvUdpJNI(): failed. could not allocate memory for buf");
}

if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) {
    free(buf);
    return (*env1)->NewStringUTF(env1, "socket");
}


bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))==-1) {
    free(buf);
    return (*env1)->NewStringUTF(env1, "bind");
}

__android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Gonna try to receive"); // TODO: Delete
//try to receive
int retval = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen); // retval equals the number of bytes(chars) received
__android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Done receive retval=[%d]",retval);// TODO: Delete
if (retval==-1) {
    return (*env1)->NewStringUTF(env1, "errRecv");
}
__android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): BUF BEFORE=[%s]",buf);// TODO: Delete
buf[retval] = '\0';
__android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): BUF AFTER=[%s]",buf);// TODO: Delete

char* target_ip;
char* next_hop_ip;

if (strcmp(inet_ntoa(cli_addr.sin_addr),MyNetworkMap->node_base_ip)==0) {                                   // MSG is an echo from myself
    __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Ignoring echo from myself");
} else {                                                                                            // MSG is not from myself, analyze
    if (IsHelloMsg(buf) == TRUE) {
        if (IsNodeForbidden(inet_ntoa(cli_addr.sin_addr)) == 1){
            __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Ignoring HELLO_MSG from  [%s]", inet_ntoa(cli_addr.sin_addr));
        }
        else{
            __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Going to process hello");// TODO: Delete
            ProcessHelloMsg(strpbrk(buf,":")+1,strlen(strpbrk(buf,":")+1),MyNetworkMap);
        }
    } else {
        __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Entering ExtractTargetFromHeader [%s]", buf); // TODO: Delete
        char* target_ip = ExtractTargetFromHeader(buf);
        char* next_hop_ip = ExtractNextHopFromHeader(buf);


        if (strcmp(inet_ntoa(cli_addr.sin_addr),MyNetworkMap->node_base_ip)==0) { // Message received is an echo from myself.
            __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): IGNORE_MSG [%s]", buf);
            is_ignore_msg = 1;
        } else {

            if (strcmp(MyNetworkMap->node_base_ip,target_ip)==0) {
                __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): I AM THE TARGET OF THE MSG [%s]", buf);
            } else if (strcmp(next_hop_ip,MyNetworkMap->node_base_ip)==0) {
                __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): I AM THE NEXT HOP OF THE MSG [%s]", buf);
                is_forward_msg = 1;
            } else {        // NOTE : For the moment we do not need messages that we are not the next hop or target of.
                            //          In the future we may want to keep this side information for opportunistic decoding.
                __android_log_print(ANDROID_LOG_INFO, "WARNING","RecvUdpJNI(): I am neither the source,target or nexthop of this message [%s]", buf);
                is_ignore_msg = 1;
            }
        }
    }
}

__android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Raw string: <%s>",buf);
//if received successfully , close socket
__android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): Received");
close(sockfd);

char* return_str = (char*)malloc(sizeof(char)*200);
if (is_ignore_msg == 1) {
    sprintf(return_str, "ignoring message [%s]",buf);
    free(buf);
    return (*env1)->NewStringUTF(env1, "ignore"); // return ignore
} else {

    if (network_coding_on == TRUE) {
        //decrypt
        __android_log_print(ANDROID_LOG_INFO, "WARNING",  "RecvUdpJNI(): Network coding decryption not yet fully implemented");
        SourceList* source_list = GetSourceFromString(buf);
        // continue decryption
    }

    if (is_forward_msg == 1) {
        //forward message
        __android_log_print(ANDROID_LOG_INFO, "WARNING",  "RecvUdpJNI(): Old next hop code for forwarding");
        strstrptr = strstr(buf,";")+1;
        __android_log_print(ANDROID_LOG_INFO, "adhoc-jni.c",  "RecvUdpJNI(): target_ip extracted before calling SendUdpJNI: <%s>",target_ip);
        SendUdpJNI(target_ip,PORT,strstrptr,1,0,strlen(strstrptr)); // TODO: When we add XOR we have to use the message length integer instead of strlen()
        sprintf(return_str, "forwarding message [%s]",buf);
        free(buf);
        return (*env1)->NewStringUTF(env1, return_str);
    } else { // I AM THE TARGET OF THE MESSAGE
        //read message
        strstrptr = strstr(buf,";");
        if (strstrptr != NULL) {
            return (*env1)->NewStringUTF(env1, strstrptr+1); // only return the MSG part
        } else {
            return (*env1)->NewStringUTF(env1, buf); // TODO: this should be an error
        }
    }
}

}

感谢任何可以救我的人:(

0 个答案:

没有答案