我有一个C ++类,它使用JNI JVM来运行Java方法。无论出于何种原因,我的程序正在进行3次迭代,在第3次循环中,JVM与SIGSEGV崩溃。
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f2af5de1c81, pid=7669, tid=139822523557696
#
# JRE version: Java(TM) SE Runtime Environment (7.0_45-b18) (build 1.7.0_45-b18)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.45-b08 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libc.so.6+0x7ac81]
此代码根本不完整。
#include <string>
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include "imgsearch.h"
#define PORT "8675"
#define BACKLOG 10
JNIEnv* create_vm() {
JavaVM* j;
JNIEnv* e;
JavaVMInitArgs j_args;
JavaVMOption opts;
j_args.version = JNI_VERSION_1_6;
j_args.nOptions = 1;
j_args.ignoreUnrecognized = 0;
char* cp = (char *)"-Djava.class.path=.:./lucene-4.4.0/analysis/common/lucene-analyzers-common-4.4.0.jar:./lucene-4.4.0/core/lucene-core-4.4.0.jar:./lucene-4.4.0/queryparser/lucene-queryparser-4.4.0.jar";
opts.optionString = cp;
j_args.options = &opts;
JNI_CreateJavaVM(&j, (void**)&e, &j_args);
return e;
}
JNIEnv* env = create_vm();
JavaVM* jvm;
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
void sockcom(int csock) {
std::cout << "Yeah!" << std::endl;
}
int main(int argc, char *argv[]) {
env->GetJavaVM(&jvm);
std::string fP = "features/esp.feature";
ImgSearch *iS;
iS = new ImgSearch();
iS->LoadFeatures(fP);
//iS->BuildClusters(150000, 15);
//iS->ClustersToFile("output.clusters");
iS->FileToClusts("output.clusters");
iS->BuildIndex();
//iS->IndexToFile("output.index");
//iS->FileToIndex("output.index");
//iS->FindNeighbors();
//iS->NeighborsToFile("output.neighbors");
iS->FileToNeighbors("output.neighbors");
iS->BagOfWords("features/imglist.txt", "features/esp.size", "coll/output.bagofwords");
iS->BuildLuceneIndex("coll/output.bagofwords");
//std::string queryfile = "queries/query1.pgm";
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char s[INET6_ADDRSTRLEN];
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
return 2;
}
freeaddrinfo(servinfo); // all done with this structure
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); }
printf("server: waiting for connections...\n");
while(1) { // main accept() loop
int pipefd[2];
int pres = pipe(pipefd);
if (pres < 0) {
perror("pipe");
continue;
}
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
printf("server: got connection from %s\n", s);
std::thread th(sockcom, new_fd);
th.detach();
std::string queryfile = "queries/query3.pgm";
iS->Search(queryfile);
}
jvm->DestroyJavaVM();
return 0;
}
所以iS-&gt;搜索(queryfile);基本上如下:
void ImgSearch::Search(std::string &filePath) {
ImgQuery newQuery(filePath, Ndx, WORDS);
newQuery.ExtractKeyPoints();
newQuery.FindNeighbors();
newQuery.BagOfWords();
newQuery.LuceneSearch();
return;
// Error Checking?
}
LuceneSearch函数是唯一使用JNI JVM的函数。
void ImgQuery::LuceneSearch() {
jclass qcls = env->FindClass("BatchSearch");
if (qcls == NULL) std::cout << "BatchSearch: Not Found." << std::endl;
jmethodID qmid = env->GetStaticMethodID(qcls, "main", "()V");
env->CallStaticVoidMethod(qcls, qmid);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
std::cout << "Still working..." << std::endl;
return;
// Error Checking?
}
基本上,我想知道的是A)你看到任何明显错误的东西吗?和B)如何在整个项目中正确地重用JVM?
编辑:有没有办法等待JVM准备好?