0

JNIネイティブコードがあります。このネイティブメソッドを呼び出して他のリクエストを実行すると、jvmがクラッシュします。

おそらく、このJNIネイティブメソッド(cコード)にメモリリークがあります。

以下のコードでメモリリークを検出するのに役立つボディはありますか?

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

0 に答える 0