Opened 20 years ago
Closed 20 years ago
#809 closed defect (fixed)
Multiple calls to vsnprintf fail with SEGV under AMD64
| Reported by: | Paul Price | Owned by: | jhoblitt |
|---|---|---|---|
| Priority: | high | Milestone: | |
| Component: | sys | Version: | unspecified |
| Severity: | normal | Keywords: | |
| Cc: |
Description
In a few places in our code base, we do something like the following:
void printFunc(const char *format, va_list ap)
{
int size = vsnprintf(NULL, 0, format, ap);
psString string = psStringAlloc(size);
vsnprintf(string, size + 1, format, ap);
now do something with string
}
Please note that, while this code works under x86 and x86_64, it produces a SEGV
on AMD64, with a trace similar to the following:
#0 0x00002aaaac9ad270 in strlen () from /lib/tls/libc.so.6
#1 0x00002aaaac981cd8 in vfprintf () from /lib/tls/libc.so.6
#2 0x00002aaaac9a0aa4 in vsnprintf () from /lib/tls/libc.so.6
#3 0x00002aaaaaebf189 in printFunc (.......)
The reason for the problem is that one cannot *technically* traverse a va_list
twice (the traversal is done in the depths of vsnprintf). While glibc for some
architectures must reset the va_list pointer to the start of the list after a
traversal, this is not guaranteed behaviour, so one must either copy the va_list
(va_copy), or start it again (va_start).
References:
- http://lists.debian.org/debian-ia64/2005/05/msg00004.html
- Harbison & Steele, p330.
Josh is writing a function, psStringAppendV, that will take care of this issue.
Then we will clean up all instances we can find.
Change History (2)
comment:1 by , 20 years ago
comment:2 by , 20 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Fixed psTrace, psLogMsg as well.

psDB has been fixed by elimating all calls to vsnprintf() by using the new
psStringAppendV() instead.