Hello,

While analyzing a complex C-written database layer with valgrind 3.9.0, I
encounter the following problem in some statement; the called functions
are putting together a database SELECT statement:

...
==17454== Conditional jump or move depends on uninitialised value(s)
==17454==    at 0x5921F10: strchrnul (in /lib/libc-2.11.3.so)
==17454==    by 0x58E55D6: vfprintf (in /lib/libc-2.11.3.so)
==17454==    by 0x59076FB: vsprintf (in /lib/libc-2.11.3.so)
==17454==    by 0x58EF96A: sprintf (in /lib/libc-2.11.3.so)
==17454==    by 0x5555A0C: select_record (sisisinst.c:1397)
==17454==    by 0x55553F4: sisisinst (sisisinst.c:933)
==17454==    by 0x553AC45: DB_rdir (dbcall.c:1894)
==17454==    by 0x5539C20: DB_ChkVer (dbcall.c:604)
==17454==    by 0x553A098: DB_opdbP (dbcall.c:955)
==17454==    by 0x5539D39: DB_opdb (dbcall.c:654)
==17454==    by 0x804BF69: InitVDaemon (ZFLVDaemon.c:715)
==17454==    by 0x804BAAC: main (ZFLVDaemon.c:413)
==17454==  Uninitialised value was created by a stack allocation
==17454==    at 0x553AA48: DB_rdir (dbcall.c:1827)

the involved fuctions are shown below; the statement in question (see below)
is

  sprintf (select_anw, sel_anw, name, name);      <********* sisisinst.c:1397

I have checked carefully the code and the 4 args to sprintf() are
all correct defined on the stack; when I change the code to:


  select_anw[0] = '\0';
  sprintf (select_anw, sel_anw, name, name); 
        
then is valgrind happy, i.e, does not raise the messages any more;

I have two questions:

1) What makes valgrind complaining about this code exactly?
2) When I write a small example like:

   #include <stdio.h>

   main() {
      char select_anw[1024];
      sprintf (select_anw, "SELECT %s.* from %s ", "bla", "bla");
   }

   I'm not able to reproduce the valgrind warning, why?

Thanks

        matthias





DB_rdir():

DB_rdir(int (*tabmodul)(), /* Name des Moduls, das die DB-Operationen
                            * fuer die gewuenschte Tabelle realisiert      */
        int key,           /* Bezeichner f. Schluessel                     */
        int scroll,        /* SCROLL-Cursor anlegen oder nicht             */
        int lock,          /* Satz sperren oder nicht                      */
        void *p_daten      /* Zeiger auf die Struktur der jeweiligen
                            * Datenbanktabelle. Vor Aufruf m?ssen die Werte
                            * der Felder, die zum Key geh?ren, gef?llt
                            * werden. Nach Ablauf der Funktion ist Struktur
                            * bei erfolgreicher Abarbeitung mit erstem Satz
                            * der Ergebnismenge gef?llt                    */
       )
{                                                                           
<******* dbcall.c:1827
/*----------------------------------------------------------------------*
 *                     DB_rdir()                                        *
 *----------------------------------------------------------------------*/
int db_ret=RC_OK;
char sel_anw[LEN_SELECT];
^^^^^^^^^^^^^^^^^^^^^^^^^
....

  /*
   * SELECT-Anweisung in Teilen zusammen setzen
   * DB_NORID: keine rowids lesen
   */
  if(lock == DB_NORID) {
    /* no rowid und scroll cursor passen nicht zusammen: Fehler */
    if(scroll == DB_SCROLL) {
      db_ret = db_errfill(DBCALL_FEHLER, RC_NORIDSCR);
      if(db_report_is_on) db_report(REPORT_FCT_OUT, "DB_rdir", db_ret);
      return(db_ret);
    }
    strcpy(sel_anw, SELECT0);
  } else {
    strcpy(sel_anw, SELECT1);
  }
  strcpy(where_anw, WHERE1);


  /*
   *  Aufruf tabellenspezifisches Modul
   */
  if(sql_trace_is_on) sybDebug("now entering tabmodul");
  db_ret = ((* tabmodul) (RDIR, scroll, lock, key, (int)DB_NOPARA, p_daten,
                          sel_anw, where_anw, (void *)NULL,
                          (char *)NULL, (char *)NULL, (char *)NULL, (char 
*)NULL, (char *)NULL, (long *)&count));



sisisinst():

/*------------------------------------------------------------------------*/
/*                    tabmodul                                            */
/*------------------------------------------------------------------------*/
int sisisinst (
     int zugriff,        /* Art der Zugriffsanforderung             */
     int scroll,         /* Typ des Satzzeigers SCROLL/NOSCROLL     */
     int lock,           /* Datensatz sperren  DB_LOCK/DB_NOLOCK    */
     int key,            /* Nummer des Schluessels f. <zugriff>     */
     int sto,            /* ein Satz oder alle (nur DB_dlet())      */
     void *p_daten,      /* Pointer auf Struktur d. DB-Tabelle      */
     char *sel_anw,      /* 1.Teil der SELECT-Anweisung             */
     char *where_anw,    /* 2.Teil der SELECT-Anw (WHERE-Bedingung) */
     void *p_btw_daten,  /* Pointer auf zustzl. Struktur            *
                          * nur fuer DB_rbtw().                     *
                          * beschreibt Obergrenze f.Bereichssuche   */
     char *order_by,     /* Liste der Spaltennamen fuer ORDER BY    */
     char *auf_ab,       /* Sortierung erfolgt aufsteigend (DB_ASC) *
                          *              bzw.  absteigend (DB_DESC) */
     char *group_by,     /* Liste der Spaltennamen fuer GROUP BY    */
     char *having,       /* Bedingung fuer HAVING                   */
     char *into_temp,    /* Name der temp. Tabelle fuer INTO TEMP   */
     long *count         /* fuer Lese-Operationen Rxxx :
                          * wenn Wert bei Aufruf
                          * DO_COUNT : Anzahl Saetze der Ergebnismenge
                          *            ermitteln und in count
                          *            zurueckgeliefern
                          * NULL     : Leseoperation durchfuehren
                          */
             )


...
  /*
   *   Verzeigung zu DB-Operation
   */
  switch (zugriff)
  {
    case  RGEQ  :
    case  RGRT  :
    case  RLEQ  :
    case  RLES  :
    case  RWHR  :
    case  RDIR  :   db_ret = select_record(scroll, lock, key,
                                           sel_anw, where_anw, p_tabdaten,
                                           NOBTW, p_oben,
                                           order_by, auf_ab, group_by,
                                           having, into_temp,
                                           count
                                          );
                    break;






select_record():

static int
select_record (
int             scroll,       /* Angabe, ob SCROLL-Cursor oder sequent.  *
                               * Cursor                                  */
int             lock,         /* Satz sperren oder nicht                 */
int             key,          /* Lesen mit einem Key oder der ganzen     *
                               * Tabelle (NOKEY)                         */
char           *sel_anw,      /* erster Teil der Select-Anweisung        */
char           *where_anw,    /* where- Klausel                          */
t_sisisinst_ec *p_daten,      /* Datensatz :   enthaelt                   *
                               * - Werte d. Schluesselfelder, nach denen  *
                               *   gesucht wird                           *
                               * - nach Suchen : 1. Satz d. Ergebnismenge *
                               * - bei Bereichssuche : Untergrenze        */
int             i_between,    /* Bereichssuche, oder nicht  (BTW/NOBTW)   */
t_sisisinst_ec  *p_oben,      /* Datensatz, Obergrenze des Suchbereichs   *
                               * bei Bereichssuche (i_between==BTW)       */
char            *order_by,    /* Liste der Spaltennamen fuer ORDER BY     */
char            *auf_ab,      /* Sortierung erfolgt aufsteigend (DB_ASC)  *
                               *              bzw.  absteigend (DB_DESC)  */
char            *group_by,    /* Liste der Spaltennamen fuer GROUP BY     */
char            *having,      /* Bedingung fuer HAVING                    */
char            *into_temp,   /* Name der temp. Tabelle fuer INTO TEMP    */
long            *count        /* wenn Wert bei Aufruf
                               * DO_COUNT : Anzahl Saetze der Ergebnismenge
                               *            ermitteln und in count
                               *            zurueckgeliefern
                               * NULL     : Leseoperation durchfuehren
                               */
  )

{
....
  char           select_anw[MAX_SEL_LEN];  /* Bereich fuer aufbereitete */
....
#ifdef ORACLE
  {
  /* how to make valgrind happy */
  char *name = TAB_SISISINST;
  sprintf (select_anw, sel_anw, name, name);      <********* sisisinst.c:1397
  }
#endif



-- 
Matthias Apitz               |  /"\   ASCII Ribbon Campaign:
E-mail: [email protected]     |  \ /   - No HTML/RTF in E-mail
WWW: http://www.unixarea.de/ |   X    - No proprietary attachments
phone: +49-170-4527211       |  / \   - Respect for open standards
                             | en.wikipedia.org/wiki/ASCII_Ribbon_Campaign

------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls. 
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________
Valgrind-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to