Alex Shulgin's find of a missing NULL check after strdup()
(87tx1or3cc.fsf@commandprompt.com) prompted me to do some testing of
libpq, when malloc/strdup returns NULL. To simulate running out of
memory, I wrote a little LD_PRELOAD library that allows causing malloc()
to return NULL, after a particular number of calls. and ran
src/test/examples/testlibpq with that hack.
After fixing all the missing NULL-checks, I found that testlibpq
sometimes just hangs. It happens when this malloc() call in
PQmakeEmptyPGResult() fails:
#3 0x00007f6dc86495c0 in malloc () from /home/heikki/mallocfail.so
#4 0x00007f6dc8423b6e in PQmakeEmptyPGresult (conn=0x1bea040,
status=PGRES_COMMAND_OK) at fe-exec.c:144
#5 0x00007f6dc8430b27 in pqParseInput3 (conn=0x1bea040) at
fe-protocol3.c:204
#6 0x00007f6dc8426468 in parseInput (conn=0x1bea040) at fe-exec.c:1652
#7 0x00007f6dc8426583 in PQgetResult (conn=0x1bea040) at fe-exec.c:1727
#8 0x00007f6dc8426c76 in PQexecFinish (conn=0x1bea040) at fe-exec.c:2000
#9 0x00007f6dc84268ad in PQexec (conn=0x1bea040, query=0x400e32
"BEGIN") at fe-exec.c:1834
#10 0x0000000000400b18 in main (argc=1, argv=0x7fffc9b6a568) at
testlibpq.c:59
When that malloc() returns NULL, parseInput returns without reading any
input. PQgetResult() takes that as a sign that it needs to read more
input from the server, before calling parseInput() again, and that read
never returns because there is no more data coming from the server.
I don't have any immediate plans to fix this, or to continue testing
this. There might well be more cases like this. Patches are welcome.
Attached is the little wrapper library I used to test this. testlibpq
hangs when run with MALLOC_FAIL_AT=110. It's really quick & dirty, sorry
about that. I'm sure there are more sophisticated tools to do similar
testing out there somewhere..
- Heikki