Обсуждение: Segmentation Fault
Hi,
I want to ask what does the error message mean by
"0x40023abb in resetPQExpBuffer () from /usr/local/pgsql/lib/libpq.so.3"?
I got this message using GDB to trace the program.
(Segmentation fault occurswhen run the program directly.)
I reviewed the program many times, and found this is only to happen when
I call the `ctime()' or `time()' in a program function.
code fragment FYI
--8<------------------------
// `res = PQexec(conn, sql)' here..
...
... } else if (!strcmp(PQfname(res, i), SYNCTIME_FIELD_NAME)) {
// puts("7"); //char chP[30]; printf("timer=%ld\n", time(timer)); // <====== without this line, the
program works
// printf("%s", ctime(time(NULL)));
// printf("%s", asctime(localtime(&timer))); sprintf(tmp, "'1999-12-11 09:50:58'::timestamp, "); strcat(p2, tmp); }
elseif (!strcmp(PQfname(res, i), SERVERID_FIELD_NAME)) { puts("8"); sprintf(tmp, "'%s'", PQgetvalue(res, 0, i));
strcat(p2,tmp); }}
...
...
freeing resources here
---------->8--------------
Thank you very much.
Frankie Lam.
>> I want to ask what does the error message mean by> "0x40023abb in resetPQExpBuffer () from
/usr/local/pgsql/lib/libpq.so.3"?>I got this message using GDB to trace the program.> (Segmentation fault occurswhen
runthe program directly.)>> I reviewed the program many times, and found this is only to happen when> I call the
`ctime()' or `time()' in a program function.>> code fragment FYI> --8<------------------------> // `res = PQexec(conn,
sql)'here..> ...> ...> }> else if (!strcmp(PQfname(res, i), SYNCTIME_FIELD_NAME))> {> // puts("7");> //char
chP[30];> printf("timer=%ld\n", time(timer)); // <====== without this line, the> program works> // printf("%s",
ctime(time(NULL)));>// printf("%s", asctime(localtime(&timer)));> sprintf(tmp, "'1999-12-11 09:50:58'::timestamp,
");
I would like to see the declaration of the "timer" variable.
Is it "time_t"? Then you should code "&timer" as in localtime(&timer).
Is it "time_t *"? Then, did you alloc'd memory?
Regards, Christoph
Oh, I'm so sorry....
I've made a stupid mistake... and this mistake is at the cost of 3 days
work.
The segmentation fault is totally irrelevant to the time functions in
previous thread.
Buggy Code Fragment FYI
--8<------------------------
..
.. len =strlen(PQgetvalue(res, 0, i)) * 2 + 1; // <========= printf("***********length=%d\n", len); tmp2 = (char *)
calloc(sizeof(char),len); strcat(p2, "'");
PQescapeString(tmp2, PQgetvalue(res, 0, i), len); // <========= this
line, // PQescapeString won't stop at '\0', so it will go out // of range of the returning value by PQgetvalue().
strcat(p2, tmp2); strcat(p2, "', "); free(tmp2); tmp2 = NULL;
..
..
---------->8--------------
Here I have one more question, is there any debugging tools other than GDB?
I'm not quite used to it, debugging segmentation fault is really a pain. :-(
Thx,
Frankie Lam
"Frankie Lam" <frankie@ucr.com.hk> wrote in message
news:b6gku9$2llu$1@news.hub.org...
> Hi,
>
> I want to ask what does the error message mean by
> "0x40023abb in resetPQExpBuffer () from /usr/local/pgsql/lib/libpq.so.3"?
> I got this message using GDB to trace the program.
> (Segmentation fault occurswhen run the program directly.)
>
> I reviewed the program many times, and found this is only to happen when
> I call the `ctime()' or `time()' in a program function.
>
> code fragment FYI
> --8<------------------------
> // `res = PQexec(conn, sql)' here..
> ...
> ...
> }
> else if (!strcmp(PQfname(res, i), SYNCTIME_FIELD_NAME))
> {
> // puts("7");
> //char chP[30];
> printf("timer=%ld\n", time(timer)); // <====== without this line, the
> program works
> // printf("%s", ctime(time(NULL)));
> // printf("%s", asctime(localtime(&timer)));
> sprintf(tmp, "'1999-12-11 09:50:58'::timestamp, ");
> strcat(p2, tmp);
> }
> else if (!strcmp(PQfname(res, i), SERVERID_FIELD_NAME))
> {
> puts("8");
> sprintf(tmp, "'%s'", PQgetvalue(res, 0, i));
> strcat(p2, tmp);
> }
> }
> ...
> ...
> freeing resources here
> ---------->8--------------
>
> Thank you very much.
>
> Frankie Lam.
>
>
>> Oh, I'm so sorry....> I've made a stupid mistake... and this mistake is at the cost of 3 days> work.> The segmentationfault is totally irrelevant to the time functions in> previous thread.> Keep your head. AFAICT segmentation faults are every C programmer's nightmare and best known for hard to find. I know of people searching for mistakes even longer and I've seen mistakes more stupid than yours. >> Here I have one more question, is there any debugging tools other than GDB?> I'm not quite used to it, debugging segmentation fault is really a pain. :-(> I don't know of one. I'm using xdb on HP-UX, which is quite similar I suppose. I've found it useful when trying to track down, do not trace, but let it simply run within the debugger and then use the "down" command to find your code area. There is also a function called memorymap(int show_stats) which often detects memory faults before the operating systems does. > len =strlen(PQgetvalue(res, 0, i)) * 2 + 1; // <========= Why not using PQgetlength(res, 0, i)?> PQescapeString(tmp2, PQgetvalue(res, 0, i), len); // <========= One last question: Why are you using PQescapeString on PQgetvalue? The doc says: If you want to include strings that have been received from a source that is not trustworthy (for example, because a random user entered them), you cannot directly include them in SQL queries for security reasons. Instead, you have to quote special characters that are otherwise interpreted by the SQL parser. So PQgetvalue is trustworthy. There should be no need to call PQescapeString, except you were using a binary cursor. But if you were using one, then why would you want to escape the result instead of just using a normal cursor? Regards, Christoph
----- Original Message ----- From: "Christoph Haller" <ch@rodos.fzk.de> > > > > Oh, I'm so sorry.... > > I've made a stupid mistake... and this mistake is at the cost of 3 days > > work. > > The segmentation fault is totally irrelevant to the time functions in > > previous thread. > > > Keep your head. > AFAICT segmentation faults are every C programmer's nightmare > and best known for hard to find. I know of people searching for > mistakes even longer and I've seen mistakes more stupid than yours. > > > > > Here I have one more question, is there any debugging tools other > than GDB? > > I'm not quite used to it, debugging segmentation fault is really a > pain. :-( > > Have you looked at efence, purify and valgrind? Regards, James Williamson www.nameonthe.net Tel: +44 208 7415453 Fax: + 44 208 7411615 > I don't know of one. I'm using xdb on HP-UX, which is quite similar I > suppose. > I've found it useful when trying to track down, do not trace, but let it > simply run > within the debugger and then use the "down" command to find your code area. > There is also a function called memorymap(int show_stats) which often > detects > memory faults before the operating systems does. > > > len =strlen(PQgetvalue(res, 0, i)) * 2 + 1; // <========= > Why not using PQgetlength(res, 0, i)? > > PQescapeString(tmp2, PQgetvalue(res, 0, i), len); // <========= > One last question: > Why are you using PQescapeString on PQgetvalue? > > The doc says: > If you want to include strings that have been received from a source > that is not trustworthy (for example, because a random user entered > them), you cannot directly include them in SQL queries for security > reasons. Instead, you have to quote special characters that are > otherwise interpreted by the SQL parser. > > So PQgetvalue is trustworthy. There should be no need to call > PQescapeString, > except you were using a binary cursor. But if you were using one, then why > would you want to escape the result instead of just using a normal cursor? > > Regards, Christoph > > > ---------------------------(end of broadcast)--------------------------- > TIP 4: Don't 'kill -9' the postmaster >
On Thu, 3 Apr 2003 19:31, Frankie Lam wrote: > Here I have one more question, is there any debugging tools other than GDB? > I'm not quite used to it, debugging segmentation fault is really a pain. I'm using Redhat 7.3, with "everything" installed. It has ddd, which is a nice frontend to gdb. More detail here: http://www.gnu.org/software/ddd/ Also you might like to consider memprof (useful in tracking down memory leaks) - another graphical tool. Hope this helps! Regards, Philip.
> > Have you looked at efence, purify and valgrind? > I will, thanks :-). (I'm a newbie)
Thanks all for replying.
> > len =strlen(PQgetvalue(res, 0, i)) * 2 + 1; // <=========
> Why not using PQgetlength(res, 0, i)?
Actually I'm quite new to libPQ, that's why I didn't know there's a
PQgetlength function. :-)
> > PQescapeString(tmp2, PQgetvalue(res, 0, i), len); // <=========
> One last question:
> Why are you using PQescapeString on PQgetvalue?
>
> The doc says:
> If you want to include strings that have been received from a source
> that is not trustworthy (for example, because a random user entered
> them), you cannot directly include them in SQL queries for security
> reasons. Instead, you have to quote special characters that are
> otherwise interpreted by the SQL parser.
hmm.., I did this on purpose. Because I want to grab SQL commands
I previously stored in a table from one database, then reformat them
and store them into another database.
E.g. the reformatted string looks like:
INSERT INTO tableOnAnotherDB(sqlCMD) values('delete from test where
name=''\\\\''');
I'm trying to implement a scale-down'ed version of synchronous
replication, only limited to replicating between two databases.
And this C program is responsible for synchronizing the two
databases and keep them consistent, in case one of them failed
and is up again later and other cases. (checking who's master, and
who's slave, are they accepting requests etc, is done by the server
side stored functions. VB + ODBC + PL/PGSQL in backend)
Regards
Frankie Lam
> >> > The doc says:> > If you want to include strings that have been received from a source> > that is not
trustworthy(for example, because a random user entered> > them), you cannot directly include them in SQL queries for
security>> reasons. Instead, you have to quote special characters that are> > otherwise interpreted by the SQL
parser.>>hmm.., I did this on purpose. Because I want to grab SQL commands> I previously stored in a table from one
database,then reformat them> and store them into another database.> E.g. the reformatted string looks like:> INSERT
INTOtableOnAnotherDB(sqlCMD) values('delete from test where> name=''\\\\''');>
Ok, I see. I didn't think of that possibility. You are right.
Regards, Christoph