|
From: Matthias A. <gu...@un...> - 2014-07-28 13:07:58
|
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: gu...@un... | \ / - 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
|