Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect va_start calls #5076

Merged
merged 1 commit into from
Oct 15, 2024
Merged

Conversation

jepler
Copy link
Contributor

@jepler jepler commented Oct 15, 2024

The 2nd argument of va_start must always be the function parameter immediately before the "..." argument. Otherwise, the behavior is undefined.

Reproducer (compile with gcc -Wvarargs):

#include <stdarg.h>
#include <stdio.h>

void wrong_va_arg(const char *format, ...) {
    va_list ap;
    const char *newFormat = "whatever";
    (void)format;

    va_start(ap, newFormat);
    vprintf(newFormat, ap);
    va_end(ap);
}

godbolt link to reproducer: https://godbolt.org/z/YMoGKb9xh

@CLAassistant
Copy link

CLAassistant commented Oct 15, 2024

CLA assistant check
All committers have signed the CLA.

@thebentern thebentern requested a review from caveman99 October 15, 2024 16:29
Copy link
Member

@caveman99 caveman99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution, but that change defeats the point of the original change. Namely to add an \n to the format string. The original code actually works while your code would just print all logging without a newline. Did you actually test the change or did you just go by the compiler warning?

The 2nd argument of va_start must always be the function parameter
immediately before the "..." argument. Otherwise, the behavior is
undefined.

Reproducer (compile with `gcc -Wvarargs`):
```c
#include <stdarg.h>
#include <stdio.h>

void wrong_va_arg(const char *format, ...) {
    va_list ap;
    const char *newFormat = "whatever";
    (void)format;

    va_start(ap, newFormat);
    vprintf(newFormat, ap);
    va_end(ap);
}
```
@jepler
Copy link
Contributor Author

jepler commented Oct 15, 2024

This does not to my knowledge "fix a bug": I checked gcc arm and gcc x86_64 and both generate the same code. It's likely a modern compiler just ignores the 2nd argument of va_start in favor of the information in the function prototype.

@jepler
Copy link
Contributor Author

jepler commented Oct 15, 2024

I am changing the second argument of va_start, which must be the named argument just before the ... argument. Since the argmuent to log_to_serial remains newFormat, the revised, added-newline version of the format string is used when actual formatting is done.

        va_list arg;
        va_start(arg, format);

        log_to_serial(logLevel, newFormat, arg);
        log_to_syslog(logLevel, newFormat, arg);

Here's a example that shows that the revised code with va_start(arg, format) + vprintf(newFormat) works properly. Godbolt version.

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int printf_with_newline(const char *format, ...) {
    // append \n to format
    size_t len = strlen(format);
    char *newFormat = new char[len + 2];
    strcpy(newFormat, format);
    newFormat[len] = '\n';
    newFormat[len + 1] = '\0';

    va_list arg;
    va_start(arg, format);            // <-- va_start argument must be the actual function argument 
    int r = vprintf(newFormat, arg);  // <-- argument to vprintf can differ
    va_end(arg);

    delete newFormat;
    return r;
}

int main() {
    printf_with_newline("Your random number is %d",
                        rand() % 6);
    printf_with_newline("this appears on its own line");
}

output:

Your random number is 1
this appears on its own line

@jepler jepler requested a review from caveman99 October 15, 2024 18:25
@caveman99
Copy link
Member

Sorry, i only reviewed that from a mobile device and thought you changed all of the occurances. I tested a few binaries now with the patch and logging is still fine.

@thebentern thebentern merged commit 25b557c into meshtastic:master Oct 15, 2024
47 checks passed
@jepler
Copy link
Contributor Author

jepler commented Oct 16, 2024

Thank you for taking a second look, I appreciate it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants