Memory leak on JNI native code

2019-08-16 17:16发布

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);
}

0条回答
登录 后发表回答