Обсуждение: Re: psqlodbc 09.01.0200 - OS X 10.6 - memory leak ?

Поиск
Список
Период
Сортировка

Re: psqlodbc 09.01.0200 - OS X 10.6 - memory leak ?

От
blegay
Дата:
Hi again,

Note : when running, "top" indicates that #MREG, RPRVT, RSIZE,  VPRVT and
VSIZE keep growing...



--
View this message in context:
http://postgresql.1045698.n5.nabble.com/psqlodbc-09-01-0200-OS-X-10-6-memory-leak-tp5750832p5750890.html
Sent from the PostgreSQL - odbc mailing list archive at Nabble.com.


Re: psqlodbc 09.01.0200 - OS X 10.6 - memory leak ?

От
blegay
Дата:
Hi,

I tried to reproduce the problem with basic C code.

Got the same problem after 17 millions inserts.

create table :
CREATE TABLE bug_127330 (urn integer,app varchar(2))

Note : I added this file to the project :
/Library/Frameworks/iODBC.framework/Versions/3.52/iODBC

//
//  main.c
//  odbctest
//
//  Created by Bruno LEGAY on 05/04/13.
//  Copyright 2013 A&C Consulting. All rights reserved.
//

#include <stdio.h>
#include <sql.h>
#include <sqlext.h>

/*
 * see Retrieving ODBC Diagnostics
 * for a definition of extract_error().
 */
static void extract_error(
                          char *fn,
                          SQLHANDLE handle,
                          SQLSMALLINT type);

int main (int argc, const char * argv[])
{
    SQLHENV env;
    SQLHDBC dbc;
    SQLHSTMT stmt;
    SQLRETURN ret;
    SQLCHAR outstr[1024];
    SQLSMALLINT outstrlen;

    int iters;

    /* Allocate an environment handle */
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);

    /* We want ODBC 3 support */
    SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);

    /* Allocate a connection handle */
    SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);

    /* Connect to the DSN oncdPostgreSQL_Unicode */
    ret = SQLDriverConnect(dbc, NULL,
"DSN=oncdPostgreSQL_Unicode;UID=postgres;PWD=postgres;", SQL_NTS,
                           outstr, sizeof(outstr), &outstrlen,
                           SQL_DRIVER_COMPLETE);

    if (SQL_SUCCEEDED(ret)) {
        printf("Connected\n");

        printf("Returned connection string was:\n\t%s\n", outstr);

        if (ret == SQL_SUCCESS_WITH_INFO) {
            printf("Driver reported the following diagnostics\n");
            extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
        }

        SQLCHAR* sqlStatement = "INSERT INTO bug_127330 (urn,app) VALUES
(?,'C')";

        /* Allocate a statement handle */
        ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);

        if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
            // infinite loop...
            while (1) {

                iters++;

                // SQL FIXER PARAMETRE($vl_iters;SQL Paramètre entrée)
                ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT,
                                       SQL_C_SLONG, SQL_INTEGER, 0, 0,
                                       &iters, sizeof(iters), NULL);

                // SQL EXECUTER($vt_sql)
                ret = SQLPrepare(stmt, sqlStatement, SQL_NTS);
                ret = SQLExecute(stmt);

                // log
                if(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
                    printf("Insert data OK : %d\n",iters);
                }

                // SQL ANNULER CHARGEMENT
                ret = SQLFreeStmt(stmt, SQL_RESET_PARAMS);
            }

            SQLFreeHandle(SQL_HANDLE_STMT, stmt);

        } else {
            printf("Error Allocating Handle: %d\n", ret);
        }

        SQLDisconnect(dbc);        /* disconnect from driver */

    } else {
        fprintf(stderr, "Failed to connect\n");
        extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
    }
    /* free up allocated handles */
    SQLFreeHandle(SQL_HANDLE_DBC, dbc);
    SQLFreeHandle(SQL_HANDLE_ENV, env);

    return 0;
}



static void extract_error(
                          char *fn,
                          SQLHANDLE handle,
                          SQLSMALLINT type) {
    SQLINTEGER     i = 0;
    SQLINTEGER     native;
    SQLCHAR     state[ 7 ];
    SQLCHAR     text[256];
    SQLSMALLINT     len;
    SQLRETURN     ret;

    fprintf(stderr,
            "\n"
            "The driver reported the following diagnostics whilst running "
            "%s\n\n",
            fn);

    do
    {
        ret = SQLGetDiagRec(type, handle, ++i, state, &native, text,
                            sizeof(text), &len );
        if (SQL_SUCCEEDED(ret))
            printf("%s:%ld:%ld:%s\n", state, i, native, text);
    }
    while( ret == SQL_SUCCESS );
}



Process:         Xcode [22709]
Path:            /Developer/Applications/Xcode.app/Contents/MacOS/Xcode
Identifier:      com.apple.dt.Xcode
Version:         4.1 (516)
Build Info:      IDEApplication-5160000~33
Code Type:       X86-64 (Native)
Parent Process:  launchd [459]

Date/Time:       2013-04-06 05:54:36.667 +0200
OS Version:      Mac OS X 10.6.8 (10K549)
Report Version:  6

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Application Specific Information:
ProductBuildVersion: 4B110f
NSCFDictionary
objc[22709]: garbage collection is ON

...



--
View this message in context:
http://postgresql.1045698.n5.nabble.com/psqlodbc-09-01-0200-OS-X-10-6-memory-leak-tp5750832p5751040.html
Sent from the PostgreSQL - odbc mailing list archive at Nabble.com.


Re: psqlodbc 09.01.0200 - OS X 10.6 - memory leak ?

От
blegay
Дата:
Hi,

I have been able to reproduce and isolate the problem in a C code...
It is related to the SQLNumResultCols ODBC function after a call to
SQLMoreResults which does not return any lines (it is an INSERT statement).

Can anybody help ?

//
//  main.c
//  odbctest
//
//  Created by Bruno LEGAY on 05/04/13.
//  Copyright 2013 A&C Consulting. All rights reserved.
//

#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include <math.h>

/*
 * see Retrieving ODBC Diagnostics
 * for a definition of extract_error().
 */
static void extract_error(
                          char *fn,
                          SQLHANDLE handle,
                          SQLSMALLINT type);

int main (int argc, const char * argv[])
{
    SQLHENV env;
    SQLHDBC dbc;
    SQLHSTMT stmt;
    SQLRETURN ret;
    SQLCHAR outstr[1024];

    SQLSMALLINT infos;
    SQLSMALLINT resultlen;


    double iters;
    SQLUSMALLINT getFuncRes;
    SQLSMALLINT nbcols;
    SQLLEN rowcount;

    /* Allocate an environment handle */
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);

    /* We want ODBC 3 support */
    SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);

    /* Allocate a connection handle */
    SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);

    /* Connect to the DSN oncdPostgreSQL_Unicode */
    /*ret = SQLDriverConnect(dbc, NULL,
"DSN=oncdPostgreSQL_Unicode;UID=postgres;PWD=postgres;", SQL_NTS,
                           outstr, sizeof(outstr), &outstrlen,
                           SQL_DRIVER_COMPLETE);*/


    SQLCHAR* dsn = (SQLCHAR*)"oncdPostgreSQL_Unicode";
    SQLCHAR* uid = (SQLCHAR*)"postgres";
    SQLCHAR* auth = (SQLCHAR*)"postgres";
    ret = SQLConnect(dbc, dsn, SQL_NTS, uid, SQL_NTS, auth, SQL_NTS);

    /*
    SQLWCHAR* dsn = "oncdPostgreSQL_Unicode";
    SQLWCHAR* uid = "postgres";
    SQLWCHAR* auth = "postgres";
    ret = SQLConnectW(dbc, dsn, SQL_NTS, uid, SQL_NTS, auth, SQL_NTS);
    */

    //strcpy((char*)dsn,"oncdPostgreSQL_Unicode");
    //strcpy((char*)uid,"postgres");
    //strcpy((char*)auth,"postgres");

    //dsn = "oncdPostgreSQL_Unicode";
    //uid = "postgres";
    //auth = "postgres";

    //ret = SQLConnectW(dbc, (SQLWCHAR*)dsn, SQL_NTS, (SQLWCHAR*)uid,
SQL_NTS, (SQLWCHAR*)auth, SQL_NTS);
    //ret = SQLConnectW(dbc, (SQLCHAR*)"oncdPostgreSQL_Unicode", SQL_NTS,
(SQLCHAR*)"postgres", SQL_NTS, (SQLCHAR*)"postgres", SQL_NTS);


    if (SQL_SUCCEEDED(ret)) {
        printf("Connected\n");

        ret = SQLGetInfo(dbc,SQL_ASYNC_MODE,&infos, sizeof(infos),
&resultlen);

        ret =
SQLSetConnectAttr(dbc,SQL_ATTR_AUTOCOMMIT,(void*)SQL_AUTOCOMMIT_ON,SQL_IS_INTEGER);

        printf("Returned connection string was:\n\t%s\n", outstr);

        if (ret == SQL_SUCCESS_WITH_INFO) {
            printf("Driver reported the following diagnostics\n");
            extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
        }

        //SQLCHAR* sqlStatement;
        //strcpy (sqlStatement,"INSERT INTO bug_127330 (urn,app,ts) VALUES
(?,'C',clock_timestamp())");
        SQLCHAR* sqlStatement = (SQLCHAR*)"INSERT INTO bug_127330
(urn,app,ts) VALUES (?,'C',clock_timestamp())";


        printf("Statement : %s\n",sqlStatement);
        while (1) {

            iters++;
            //printf("iters : %d\n",iters);

            /* Allocate a statement handle */
            ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);

            //printf("AllocHandle : %i \n",ret);
            if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
                // infinite loop...

                    SQLGetFunctions(dbc,SQL_API_SQLPUTDATA,&getFuncRes);

                    // SQL FIXER PARAMETRE($vl_iters;SQL Paramètre entrée)
                    //ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT,
                    //                       SQL_C_SLONG, SQL_INTEGER, 0, 0,
                    //                       &iters, sizeof(iters), NULL);


                    // SQL EXECUTER($vt_sql)
                    ret = SQLPrepare(stmt, sqlStatement, SQL_NTS);

                    ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT,
                                       SQL_C_DOUBLE, SQL_DOUBLE, 7, 0,
                                       &iters, sizeof(iters), NULL);


                    ret = SQLExecute(stmt);

                    ret = SQLNumResultCols(stmt,&nbcols);

                    ret = SQLMoreResults(stmt);

                    //=======================================
                    // This call will generate leaks !!!
                    ret = SQLNumResultCols(stmt,&nbcols);
                    //=======================================

                    ret = SQLRowCount(stmt,&rowcount);

                    if (fmod(iters,1000) == 0)
                        printf("Insert data OK : %g\n",iters);

                    // SQL ANNULER CHARGEMENT
                    //ret = SQLFreeStmt(stmt, SQL_RESET_PARAMS);

                    SQLFreeHandle(SQL_HANDLE_STMT, stmt);

                } else {
                    printf("Error Allocating Handle: %d\n", ret);
                }

        }
        SQLDisconnect(dbc);        /* disconnect from driver */

        printf("Disconnected\n");

    } else {
        fprintf(stderr, "Failed to connect\n");
        extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
    }
    /* free up allocated handles */
    SQLFreeHandle(SQL_HANDLE_DBC, dbc);
    SQLFreeHandle(SQL_HANDLE_ENV, env);

    return 0;
}



static void extract_error(
                          char *fn,
                          SQLHANDLE handle,
                          SQLSMALLINT type) {
    SQLINTEGER     i = 0;
    SQLINTEGER     native;
    SQLCHAR     state[ 7 ];
    SQLCHAR     text[256];
    SQLSMALLINT     len;
    SQLRETURN     ret;

    fprintf(stderr,
            "\n"
            "The driver reported the following diagnostics whilst running "
            "%s\n\n",
            fn);

    do
    {
        ret = SQLGetDiagRec(type, handle, ++i, state, &native, text,
                            sizeof(text), &len );
        if (SQL_SUCCEEDED(ret))
            printf("%s:%i:%i:%s\n", state, i, native, text);
    }
    while( ret == SQL_SUCCESS );
}



<http://postgresql.1045698.n5.nabble.com/file/n5751192/with_leak.png>
<http://postgresql.1045698.n5.nabble.com/file/n5751192/without_leak.png>



--
View this message in context:
http://postgresql.1045698.n5.nabble.com/psqlodbc-09-01-0200-OS-X-10-6-memory-leak-tp5750832p5751192.html
Sent from the PostgreSQL - odbc mailing list archive at Nabble.com.


Re: psqlodbc 09.01.0200 - OS X 10.6 - memory leak ?

От
Heikki Linnakangas
Дата:
On 08.04.2013 14:05, blegay wrote:
> Hi,
>
> I have been able to reproduce and isolate the problem in a C code...
> It is related to the SQLNumResultCols ODBC function after a call to
> SQLMoreResults which does not return any lines (it is an INSERT statement).
>
> Can anybody help ?

I think this is the same bug that I spotted a few weeks back:
http://www.postgresql.org/message-id/5143041A.20605@vmware.com.

Your test case isn't exactly the same, but the same patch seems to fix
yours, too.

I've been meaning to commit that, along with a bunch of other fixes. But
I've been holding back because I'd actually want to migrate the psqlodbc
repository to git first. In any case, that should be fixed in the next
version.

Thanks for the report!

- Heikki


Re: psqlodbc 09.01.0200 - OS X 10.6 - memory leak ?

От
Bruno LEGAY
Дата:
Hi,

Spot on. Your patch fixed the leak :-)

Great. Thank you !!!

Bruno

Le 8 avr. 2013 à 14:53, Heikki Linnakangas a écrit :

> On 08.04.2013 14:05, blegay wrote:
>> Hi,
>>
>> I have been able to reproduce and isolate the problem in a C code...
>> It is related to the SQLNumResultCols ODBC function after a call to
>> SQLMoreResults which does not return any lines (it is an INSERT statement).
>>
>> Can anybody help ?
>
> I think this is the same bug that I spotted a few weeks back:
http://www.postgresql.org/message-id/5143041A.20605@vmware.com.
>
> Your test case isn't exactly the same, but the same patch seems to fix yours, too.
>
> I've been meaning to commit that, along with a bunch of other fixes. But I've been holding back because I'd actually
wantto migrate the psqlodbc repository to git first. In any case, that should be fixed in the next version. 
>
> Thanks for the report!
>
> - Heikki
>