[freetds] [ freetds-Patches-1120675 ] new features in ctlib

ZIGLIO, Frediano, VF-IT Frediano.Ziglio at vodafone.com
Mon Feb 14 08:27:15 EST 2005


> 
> Il giorno ven, 11-02-2005 alle 10:28 +0000, Thompson, Bill D 
> (London) ha
> scritto:
> > Freddy,
> > 
> > In order to get this code to compile with my ancient 
> compiler, I had to
> > change a bit of your code in login.c
> > My compiler will only accept initialisation with constant values...
> > 
> 
> Ok, fixed.
> 
> > I've rejigged the structure of the ctlib include files 
> > (previously pretty much everything was in cspublic.h)
> > - so the diff shows big differences, although really there is little
> > changed.
> > 
> > There are mercifully few changes necessary to tds code 
> (shows how mature
> > it is I guess)
> > I'm pretty sure none of these should functionally affect 
> odbc code...
> > 
> > Bill
> > 
> 
> Committed!
> 
> ODBC works correctly :) ctlib not :(
> - cancel test fails. It gets all rows instead of stopping... I don't
> understand why and enabling logging just core cause tdsdump_log is not
> reentrant...
> - ct_cursor fails with "ct_cmd_props() CS_CUR_STATUS != 
> CS_CURSTAT_NONE"
>   Also it has a problem with memory, from log (attached):
> 
>   ==10866== 1 errors in context 1 of 1:
>   ==10866== Invalid read of size 2
>   ==10866==    at 0x1B90D4A3: ct_cmd_props (ct.c:2476)
>   ==10866==    by 0x804935D: main (ct_cursor.c:256)
>   ==10866==  Address 0x1BABAC80 is 64 bytes inside a block of size 72
> free'd
> 
> It try to read freed memory
> 
>   ==10866==    at 0x1B905269: free (vg_replace_malloc.c:153)
>   ==10866==    by 0x1B916048: tds_free_cursor (mem.c:677)
>   ==10866==    by 0x1B918689: tds_process_cursor_tokens (token.c:3361)
>   ==10866==    by 0x1B91C1CF: tds_process_result_tokens (token.c:750)
>   ==10866==    by 0x1B910CA4: ct_results (ct.c:1132)
>   ==10866==    by 0x8049245: main (ct_cursor.c:248)
> 
> cursor seems already freed here...
> 

More on this for TDS 7+

in src/ctlib/ct.c

                if (cursor->status.dealloc == _CS_CURS_TYPE_REQUESTED){
                        ret = tds_cursor_dealloc(tds, cursor);
                        cmd->cursor = NULL;
                        cursor->status.dealloc = _CS_CURS_TYPE_SENT;
                        tds_free_all_results(tds);
                }

in src/tds/query.c

        /*
         * in TDS 5 the cursor deallocate function involves
         * a server interaction. The cursor will be freed
         * when we receive acknowledgement of the cursor
         * deallocate from the server. for TDS 7 we do it
         * here...
         */

        if (IS_TDS7_PLUS(tds)) {
                if (cursor->status.dealloc == TDS_CURSOR_STATE_SENT ||
                        cursor->status.dealloc ==
TDS_CURSOR_STATE_REQUESTED) {
                        tdsdump_log(TDS_DBG_ERROR,
"tds_cursor_dealloc(): freeing cursor \n");
                        tds_free_cursor(tds, cursor);
                }
        }

So we free cursor and then we use freed memory just after... after
tds_cursor_dealloc call upper libraries should consider cursor freed...

>From http://lists.ibiblio.org/pipermail/freetds/2004q4/017519.html

"Now there is only a sligtly difference between dynamic and cursor
behavior:
1) dynamic get created calling tds_submit_prepare (which call
tds_alloc_dynamic) while cursors are allocated using tds_alloc_cursor
2) cursors get freed by tds_cursor_dealloc while tds_submit_unprepare do
not free dynamic

1) I don't know what behavior it's better...
2) in ODBC I have a problem freeing dynamic if tds state it's not idle
cause I need to close dynamic on server side too. Perhaps it's better to
call a function in libTDS that in this case store dynamic and free it
when possible. Personally if a client library call tds_alloc_* it should
be better that client library call tds_free_* too so perhaps it would be
better if libTDS allocate cursor declaring cursor (tds_cursor_declare)"

freddy77


More information about the FreeTDS mailing list