I have a piece of JNI native code. When we invoked this native method + run other requests, the jvm will crash.
Most probably, there is memory leak in this piece of JNI native method ( c code).
Any body can help detect the memory leak in the below code?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fns_data.h"
#include "fns_client.h"
#include "sockRW.h"
#include "/usr/local/include/jni.h"
#include "JNIiSearchLib.h"
#include "com_eds_wise_util_JNIiSearchLib.h"
JNIEXPORT jstring JNICALL
Java_com_eds_wise_util_JNIiSearchLib_jniFNSSearchClient (
JNIEnv *env, jobject obj, jstring jip_addr, jint jport_number,
jstring jfield, jstring jquery_str, jint jhitnum)
{
HitIds *hit_list = NULL;
hitListPktStruct *hitPkt = NULL;
int hit_number = 0;
int i = 0;
int fnsErrno = 0;
char *result_str = NULL;
jstring rslt_str = NULL;
const char *cip_addr = NULL;
const char *cquery_str = NULL;
char errbuf[1024];
cip_addr = (*env)->GetStringUTFChars(env, jip_addr, 0);
if (cip_addr == NULL) {
return ((* env)->NewStringUTF (env, "Error: Cannot get IP address."));
}
cquery_str = (*env)->GetStringUTFChars(env, jquery_str, 0);
if (cquery_str == NULL) {
(*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);
//(*env)->DeleteLocalRef(env, cip_addr);
return ((* env)->NewStringUTF (env, "Error: Cannot get query string."));
}
printf ("[Java_JNILib_jniFNSSearchClient] ipaddress[%s] portnumber[%d]"
" querystr[%s]\n\n", cip_addr, jport_number, cquery_str);
/* Search and get back the handler & total hits
*/
hit_list = fns_search_client0 ((char *)cip_addr, jport_number,
"PN", (char *)cquery_str, &hit_number);
fnsErrno = fns_error_message();
if (fnsErrno) {
printf ("Error %d during fns_search_client0()\n", fnsErrno);
sprintf (errbuf, "Error: fns_search_client0() returns %d.", fnsErrno);
rslt_str = (* env)->NewStringUTF (env, errbuf);
(*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);
(*env)->ReleaseStringUTFChars (env, jquery_str, cquery_str);
//(*env)->DeleteLocalRef(env, cip_addr);
//(*env)->DeleteLocalRef(env, cquery_str);
fflush(stdout);
return (rslt_str);
}
/* Display total hits
*/
printf ("Total hits = %d\n", hit_number);
/* Use the handler as parameter to retrieve the actual result
*/
if (hit_number > 0) {
fns_display_ids0 ((char *)cip_addr, jport_number, hit_list,
0, hit_number - 1, &hitPkt);
fnsErrno = fns_error_message();
if (fnsErrno) {
printf ("Error %d during fns_display_ids0()\n", fnsErrno);
sprintf (errbuf, "Error: fns_display_ids0() returns %d.", fnsErrno);
rslt_str = (* env)->NewStringUTF (env, errbuf);
if (hit_list) {
FREE_STRING (hit_list);
}
(*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);
(*env)->ReleaseStringUTFChars (env, jquery_str, cquery_str);
//(*env)->DeleteLocalRef(env, cip_addr);
//(*env)->DeleteLocalRef(env, cquery_str);
fflush(stdout);
return (rslt_str);
}
}
/* Enumerate every item in the result list and display them.
* The results are returned as a string to Java in the following manner:
*
* "[hitresult1|hitresult2|hitresult3|..|hitresultN]\0"
*
* where hitresultN = 94-byte record
*
* [+string94+|+string94]+stringTerminator
*/
printf ("malloc[%d]\n", (hit_number * 95) + 3);
result_str = malloc (((hit_number * 95)+3) * sizeof(char));
if (result_str == NULL) {
printf ("Out of memory, unable to malloc\n");
rslt_str = (* env)->NewStringUTF (env, "Error: Out of memory, unable to malloc");
if (hit_list) {
FREE_STRING (hit_list);
}
if (hitPkt) {
FREE_HITLIST_STRUCT (hitPkt);
}
(*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);
(*env)->ReleaseStringUTFChars (env, jquery_str, cquery_str);
//(*env)->DeleteLocalRef(env, cip_addr);
//(*env)->DeleteLocalRef(env, cquery_str);
fflush(stdout);
return (rslt_str);
}
sprintf (result_str, "[");
for (i = 0; i < hit_number; i++) {
strcat (result_str, hitPkt->docNameList[i]);
if (i != (hit_number - 1)) {
strcat (result_str, "|");
}
}
strcat (result_str, "]");
printf ("\n\nFNS search result:[From Library]\n");
printf ("%s\n\n",result_str);
/* free the handler
*/
if (hit_list) {
FREE_STRING (hit_list);
}
/* free the result lists
*/
if (hitPkt) {
FREE_HITLIST_STRUCT (hitPkt);
}
/* prepare stuff for Java
*/
rslt_str = (* env)->NewStringUTF (env, result_str);
/* free our memory
*/
if (result_str) {
free (result_str);
}
(*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);
(*env)->ReleaseStringUTFChars (env, jquery_str, cquery_str);
//(*env)->DeleteLocalRef(env, cip_addr);
//(*env)->DeleteLocalRef(env, cquery_str);
fflush(stdout);
return (rslt_str);
}