mridoni / gixsql

GixSQL is an ESQL preprocessor and a series of runtime libraries to enable GnuCOBOL to access PostgreSQL, ODBC, MySQL, Oracle and SQLite databases.
GNU General Public License v3.0
16 stars 8 forks source link

SqlVar.cpp: invalid read of size 2 #158

Open GitMensch opened 1 year ago

GitMensch commented 1 year ago

Because of not finding why the application doesn't work any more after updating to the current version, I've run the application through valgrind.

Result:

Invalid read of size 2
   at 0xB85E5AA: SqlVar::createRealData() (SqlVar.cpp:116)
   by 0xB8074EF: Cursor::createRealDataforParameters() (Cursor.cpp:139)
   by 0xB807588: Cursor::getParameterValues() (Cursor.cpp:162)
   by 0x13B6A8E0: DbInterfacePGSQL::cursor_open(std::shared_ptr<ICursor> const&) (DbInterfacePGSQL.cpp:644)
   by 0xB8445AD: GIXSQLCursorOpen (gixsql.cpp:755)

https://github.com/mridoni/gixsql/blob/79f6247481916dede9ede79fd949aaabda756096/runtime/libgixsql/SqlVar.cpp#L115-L121

"Of course" nearly all CursorOpen work without an error in valgrind, there's only one... Not sure if/how I can help to debug that...

GitMensch commented 1 year ago

This seems like a possible show-stopper :-/

mridoni commented 1 year ago

I am investigating this, but I cannot reproduce it: the test cases have no "Invalid read" when running under Valgrind. Could you send me the cursor definition you are using, COBOL definition of the fields it references in the FETCH statement and, if possibile the DB definitions of the columns? Obviously change the names of the columns or fields if needed for privacy.

Thanks

GitMensch commented 1 year ago

I'd try that on Wednesday, but would prefer to do that on a current version - can you possibly release a "dev" or "preview" pre-release until then?

mridoni commented 1 year ago

I will try but I cannot make promises: unfortunately my day-job has been taking a heavy toll for the last few months.

mridoni commented 1 year ago

I will try but I cannot make promises: unfortunately my day-job has been taking a heavy toll for the last few months.

(Pre)-released autoconf-enabled tarball for v1.0.21dev.

Thanks

GitMensch commented 1 year ago

Rechecked:

==3632701== Invalid read of size 2
==3632701==    at 0x93E3A90: SqlVar::createRealData() (SqlVar.cpp:119)
==3632701==    by 0x938405A: Cursor::createRealDataforParameters() (Cursor.cpp:139)
==3632701==    by 0x9384120: Cursor::getParameterValues() (Cursor.cpp:162)
==3632701==    by 0xCBBE64C: DbInterfacePGSQL::cursor_open(std::shared_ptr<ICursor> const&) (DbInterfacePGSQL.cpp:645)
==3632701==    by 0x93C1565: GIXSQLCursorOpen (gixsql.cpp:761)
==3632701==    by 0x129FE6BF: [COBOL stack]
==3632701==  Address 0x1ffefe5ec8 is on thread 1's stack
==3632701==  13960 bytes below stack pointer

I'll possibly try to compile libgixsql with sanitizers to see if those find more.

GitMensch commented 1 year ago

Installation of libasan and libusan and configuring with -fsanitize=address -fsanitize=undefined for CXXFLAGS and LDFLAGS took a while (actually the make did took very long) and led to the need to LD_PRELOAD libasan (because cobcrun wasn't built with it) - but didn't result in any output useful output for this or #159.

Could you send me the cursor definition you are using, COBOL definition of the fields it references in the FETCH statement and, if possibile the DB definitions of the columns? Obviously change the names of the columns or fields if needed for privacy.

It happens at the second time when the cursor is opened (closed in the meantime). The declaration of the cursor is:

GIXSQL*    EXEC SQL AT :DB
GIXSQL*       DECLARE CSKEY01NG CURSOR FOR
GIXSQL*          SELECT PRIMID, MODTIME FROM TAB
GIXSQL*          WHERE
GIXSQL*             KEY01 >  (
GIXSQL*                 RPAD(:TABART         , 008, Chr(1))
GIXSQL*              || RPAD(:TABSCHL          , 020, Chr(1))
GIXSQL*                      )
GIXSQL*          ORDER BY KEY01 ASC
GIXSQL*    END-EXEC.

Those two bind variables are plain PIC X(8) and PIC X(20), the result variables are PIC S9(018) (ID) and PIC X(026) for the timestamp. All fields are "character varying" with the same size as the COBOL fields but the ID which is a "bigint".

All of the DECLARE, OPEN and FETCH statements are in the same section.