BScEE での私の最後のプロジェクトでは、アドホック ネットワークを作成しようとしています。私は Galaxy S2 デバイスで作業しており、ほとんどのコードを C ( JNI ) で記述しています。通常のメッセージを送信する以外に、5 秒ごとにブロードキャストを自動的に送信しています。データの受信をリッスンして待機しているスレッドがあります。セグメンテーション違反が原因でクラッシュし続けます- ndk-stack と addr2line を使用すると、 recvfrom が示されます :
int retval = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen);
ほとんどの場合、実行中のスレッドが受信を待機しているため、それは誤警報であり、セグメンテーション問題は別の場所にあります。
セグメンテーション違反の原因をデバッグするにはどうすればよいですか。実際に recvfrom() コードが原因である場合はどうすればよいですか。[お役に立てれば、ここに墓石を追加できます]
編集 1: 墓石の長さは 2700 行です。最初と最後を追加しました。最後に、recvfrom に誘導するアプリが含まれています。
墓石の始まり:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
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
}
}
}
}
ここで私を救ってくれる人に感謝します:(