Java运行时环境检测到致命错误:无法编写核心转储。核心转储已被禁用

时间:2016-07-01 17:06:54

标签: java c java-native-interface

非常感谢你阅读这篇文章,

我正在使用java和c开发一个匿名聊天应用。我决定使用jni将c代码集成到java中。当我尝试建立连接并发送数据包时,它会因提到的错误而崩溃。我在网上搜索太多,但没有什么可以解决这个问题。我认为在C代码的某处我提交了一个关键的访问冲突或我编写的jni代码缺少部分。再次感谢您的大力帮助。这是错误消息和涉及的代码片段。

错误日志文件链接 https://www.dropbox.com/s/oy4k5uwz7mbyqiw/hs_err_pid13072.log?dl=0

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f21816b7d18, pid=13072, tid=0x00007f212eb1c700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_92-b14) (build 1.8.0_92-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.92-b14 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x6dfd18]  jni_GetStringUTFChars+0xb8
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/burhan/workspace/AnonymousChatApplication/hs_err_pid13072.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
/home/burhan/workspace/AnonymousChatApplication/nbproject/build-impl.xml:1039: The following error occurred while executing this line:
/home/burhan/workspace/AnonymousChatApplication/nbproject/build-impl.xml:804: Java returned: 134
BUILD FAILED (total time: 8 seconds)

错误输出消息

static {    
    System.loadLibrary("Send");
}  
public void sending(String ip, String message){
    int i=0;
    for(String s:splitMessage(message)){
        sender(2, ip, String.valueOf(i++));    // JNI NATIVE METHOD CALL
        sender(2, ip, s);                      // JNI NATIVE METHOD CALL
    }
}

以上部分是我称之为jni库的部分

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <jni.h>
#include "ChatUtility_PeerConnection.h"
#include <time.h>
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#define MY_DEST_MAC0    0xFF
#define MY_DEST_MAC1    0xFF
#define MY_DEST_MAC2    0xFF
#define MY_DEST_MAC3    0xFF
#define MY_DEST_MAC4    0xFF
#define MY_DEST_MAC5    0xFF

#define BUF_SIZE    1500
#define DEFAULT_IF  "eth0"

struct pseudo_header {
u_int32_t source_address;
u_int32_t dest_address;
u_int8_t placeholder;
u_int8_t protocol;
u_int16_t udp_length;
};

unsigned short csum(unsigned short *ptr, int nbytes) {
register long sum;
unsigned short oddbyte;
register short answer;

sum = 0;
while (nbytes > 1) {
    sum += *ptr++;
    nbytes -= 2;
}

if (nbytes == 1) {
    oddbyte = 0;
    *((u_char*) &oddbyte) = *(u_char*) ptr;
    sum += oddbyte;
}

sum = (sum >> 16) + (sum & 0xffff);
sum = sum + (sum >> 16);
answer = (short) ~sum;

return (answer);
}
JNIEXPORT void JNICALL Java_ChatUtility_PeerConnection_sender
  (JNIEnv *env, jclass jClass, jint arg1, jstring arg2, jstring arg3){

    int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
int tx_len = 0;
int pack_Id = 12345;
    const char *peerIP = (*env)->GetStringUTFChars(env,arg2,0);
    const char *message = (*env)->GetStringUTFChars(env,arg3,0);
srand(time(NULL));
pack_Id = rand();

    char destination_ip[32];
strcpy(destination_ip, peerIP);

/* packet */
char sendbuf[BUF_SIZE];

/* zero out the packet */
memset(sendbuf, 0, BUF_SIZE);

/* ethernet header */
struct ether_header *eh = (struct ether_header *) sendbuf;

/* ip header */
struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header));

/* udp header */
struct udphdr *udph = (struct udphdr *) (sendbuf + sizeof(struct ether_header) + sizeof(struct iphdr));

/* data */
char *data = sendbuf + sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct udphdr);

struct sockaddr_ll socket_address;

char ifName[IFNAMSIZ];

/* Get interface name */
strcpy(ifName, DEFAULT_IF);

/* get data */
if (arg1 > 1)
    strcpy(data, message);
else
    strcpy(data, "Message Not Captured");

/* Open RAW socket to send on */
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
    perror("Socket Error");
}

int broadcast = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) == -1) {
    perror("Failed to broadcast");
    exit(1);
}

/* Get the index of the interface to send on */
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
    perror("SIOCGIFINDEX");

/* Get the MAC address of the interface to send on */
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
    perror("SIOCGIFHWADDR");

/* Ethernet header */
eh->ether_shost[0] = 0xAA;
eh->ether_shost[1] = 0xBB;
eh->ether_shost[2] = 0xCC;
eh->ether_shost[3] = 0xDD;
eh->ether_shost[4] = 0xEE;
eh->ether_shost[5] = 0xFF;
eh->ether_dhost[0] = MY_DEST_MAC0;
eh->ether_dhost[1] = MY_DEST_MAC1;
eh->ether_dhost[2] = MY_DEST_MAC2;
eh->ether_dhost[3] = MY_DEST_MAC3;
eh->ether_dhost[4] = MY_DEST_MAC4;
eh->ether_dhost[5] = MY_DEST_MAC5;

/* Ethertype field */
eh->ether_type = htons(ETH_P_IP);

/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;

/* Address length*/
socket_address.sll_halen = ETH_ALEN;

/* Destination MAC */
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;

char source_ip[32], *pseudogram;
struct pseudo_header psh;   

strcpy(source_ip, "1.2.3.4"); // Spoofed IP


/* IP Header */
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(data));
iph->id = htons(pack_Id); //ID of this packet
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = IPPROTO_UDP;
iph->check = 0; //Set to 0 before calculating checksum
iph->saddr = inet_addr(source_ip);
iph->daddr = inet_addr(destination_ip); // Destination IP Address

/* IP Checksum */
iph->check = csum((unsigned short *) iph, 20);

/* UDP Header */
udph->source = htons(7777);
udph->dest = htons(7777);
udph->len = htons(8 + strlen(data));
udph->check = 0; //Set to 0 before calculating checksum

/* UDP Checksum Pseudoheader */
psh.source_address = inet_addr(source_ip);
psh.dest_address = inet_addr(destination_ip);   // Destination IP Address
psh.placeholder = 0;
psh.protocol = IPPROTO_UDP;
psh.udp_length = htons(sizeof(struct udphdr) + strlen(data));

int psize = sizeof(struct pseudo_header) + sizeof(struct udphdr) + strlen(data);
pseudogram = malloc(psize);

memcpy(pseudogram, (char*) &psh, sizeof(struct pseudo_header));
memcpy(pseudogram + sizeof(struct pseudo_header), udph, sizeof(struct udphdr) + strlen(data));

/* Set the UDP Checksum */
udph->check = csum((unsigned short*) pseudogram, psize);

/* Final transmit length in bytes */
tx_len = sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(data);

/* Send Packet */
if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*) &socket_address, sizeof(struct sockaddr_ll)) < 0) {
    printf("Send failed\n");
}
else {
    printf("Packet sent! (%d bytes)\n", tx_len);
}
//return 0;  
     (*env)->ReleaseStringUTFChars(env, arg2, peerIP);
     (*env)->ReleaseStringUTFChars(env, arg3, message);
  }

C中的Jni库函数

1 个答案:

答案 0 :(得分:0)

我认为问题在于:

  

const char * peerIP =(* env) - &gt; GetStringUTFChars(env,arg2,0);

了解JNI functions

最后一个参数shout是指向jboolean的指针,而不是0。

此外,如果你使用jni,-Xcheck:jni应该是你的朋友=)

好的,如果你试试

jboolean isCopy1; jboolean isCopy2; const char *peerIP = (*env)->GetStringUTFChars(env, arg2, &isCopy1); const char *message = (*env)->GetStringUTFChars(env, arg3, &isCopy2);

在崩溃转储中,什么将位于本机堆栈的顶部?

  

V [libjvm.so + 0x6dfd18] jni_GetStringUTFChars + 0xb8

是不是?