Fix #678: Fix stats print on ARM due to indeterminate state of "va_list" parameter after vasprintf#933
Fix #678: Fix stats print on ARM due to indeterminate state of "va_list" parameter after vasprintf#933IgnoreWarnings wants to merge 2 commits into
Conversation
13e4aa0 to
f2f7cb0
Compare
Specifiying the "va" parameter as reference to ensure reproducable behavior on arm and x86. Signed-off-by: Pascal Bauer <pascal.bauer@rwth-aachen.de>
vstrcatf now copies the va_list parameter to prevent it beeing undetermined after call to vasprintf. See full desciption in #678. Signed-off-by: Pascal Bauer <pascal.bauer@rwth-aachen.de>
f2f7cb0 to
844a1c1
Compare
|
|
||
| char *vstrcatf(char **dest, const char *fmt, va_list ap) { | ||
| char *vstrcatf(char **dest, const char *fmt, va_list &ap) { | ||
| char *tmp; |
There was a problem hiding this comment.
I would add null pointer checks for dest and fmt
| double randf() { return (double)random() / RAND_MAX; } | ||
|
|
||
| char *vstrcatf(char **dest, const char *fmt, va_list ap) { | ||
| char *vstrcatf(char **dest, const char *fmt, va_list &ap) { |
There was a problem hiding this comment.
I'm surprised you don't need const char* restrict fmt.
There was a problem hiding this comment.
To my knowledge restrict is a C not C++ keyword?
Are you concerned about aliasing between the *dest and fmt pointers?
I dont fully understand, why we might need it..
| va_arg(ap, double); | ||
| } else if (strcmp(format, "%s") == 0) { | ||
| va_arg(ap, char *); | ||
| } |
There was a problem hiding this comment.
Not sure if this is real-time critical code. But you could avoid one allocation by doing:
size_t n = vsnprintf(NULL, 0, fmt, va_copy);
*dest = (char *)(realloc(*dest, n + i + 1));
vsnprintf(*dest + n, n+1, fmt, va_copy);There was a problem hiding this comment.
I am wondering, isnt it also UB to call vsnprintf again with the same va_copy?
@IgnoreWarnings wrote in #678
This bug occures because "va_list" is used after beeing passed to "vasprintf", which leads to undeterministic behavior.
Functions like "vasprintf" "invoke va_arg at least once, the value of arg is indeterminate after the return." (https://en.cppreference.com/w/c/io/vfprintf : Notes).
|
Hi @IgnoreWarnings, I think a found a nicer solution to the issue in #935. What do you think about it? Thanks for the analysis. I definitely learned something new :) |
Feel free to solve this issue however you like. |
|
Moved to #935 . |
The state of "va_list" parameter is indeterminant after a call to vasprintf, which causes UB on ARM.
For detailed error explanation: #678.
@stv0g
I made the decision to put the responsibility of advancing the list in the called function rather than the caller because this is how the existing code in table.cpp:void Table::row(int count, ...) assumes it should work.
@fwege