Skip to content

fix: format linker plugin messages via C shim and prints full log messages.#1774

Merged
davidlattimore merged 1 commit intowild-linker:mainfrom
Blazearth:fix-Linker-plugin-log-messages
Mar 28, 2026
Merged

fix: format linker plugin messages via C shim and prints full log messages.#1774
davidlattimore merged 1 commit intowild-linker:mainfrom
Blazearth:fix-Linker-plugin-log-messages

Conversation

@Blazearth
Copy link
Copy Markdown
Contributor

#1662 fixes linker plugin message handling by correctly formatting printf-style variadic arguments.
Introduced a small C shim that accepts the variadic arguments and formats the message via vsnprintf and sends the formatted string back to rust.
Works on stable rust and avoids c_variadics until its stable.
Added a test to verify fomatting correctness.

@Blazearth Blazearth force-pushed the fix-Linker-plugin-log-messages branch 2 times, most recently from 2beb20f to 66e9109 Compare March 28, 2026 17:48
@Blazearth
Copy link
Copy Markdown
Contributor Author

Should I remove test_plugin_message_shim.c since the existing integration test covers the fix? Or is there value in keeping it as a standalone C-level unit test?"

@davidlattimore
Copy link
Copy Markdown
Member

Thanks for implementing this. The PR looks good to me. Regarding the C test, I'd say given that it's not being executed when we run cargo test, that we should perhaps delete it. You could however copy its contents into a comment on this PR for easy access if we want it in future.

@Blazearth Blazearth force-pushed the fix-Linker-plugin-log-messages branch from 66e9109 to e88af44 Compare March 28, 2026 21:35
@Blazearth
Copy link
Copy Markdown
Contributor Author

/*
 * Standalone test for wild_plugin_message_callback.
 * Simulates what a linker plugin does: calls the callback with printf-style args.
 * Verifies that wild_handle_plugin_message receives the fully-formatted string.
 *
 * Compile and run (from workspace root):
 *   gcc -o /tmp/test_shim libwild/tests/test_plugin_message_shim.c libwild/src/plugin_message_shim.c && /tmp/test_shim
 */

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

/* Track what Rust would receive */
static int received_level = -1;
static char received_message[256];

/* Stub for the Rust function */
void wild_handle_plugin_message(int level, const char *message) {
    received_level = level;
    strncpy(received_message, message, sizeof(received_message) - 1);
    received_message[sizeof(received_message) - 1] = '\0';
}

/* The function under test */
void wild_plugin_message_callback(int level, const char *fmt, ...);

static int passed = 0;
static int failed = 0;

static void check(const char *test, int level, const char *expected) {
    if (received_level == level && strcmp(received_message, expected) == 0) {
        printf("PASS: %s\n", test);
        passed++;
    } else {
        printf("FAIL: %s\n  expected level=%d msg=\"%s\"\n  got     level=%d msg=\"%s\"\n",
               test, level, expected, received_level, received_message);
        failed++;
    }
    /* reset */
    received_level = -1;
    received_message[0] = '\0';
}

int main(void) {
    /* Test 1: plain string, no format args */
    wild_plugin_message_callback(0, "hello world");
    check("plain string", 0, "hello world");

    /* Test 2: %s substitution */
    wild_plugin_message_callback(1, "failed at %s", "main.c");
    check("string substitution", 1, "failed at main.c");

    /* Test 3: %s and %d substitution */
    wild_plugin_message_callback(2, "error at %s:%d", "foo.c", 42);
    check("string+int substitution", 2, "error at foo.c:42");

    /* Test 4: error level (2) */
    wild_plugin_message_callback(2, "undefined symbol: %s", "my_func");
    check("error level", 2, "undefined symbol: my_func");

    /* Test 5: fatal level (3) */
    wild_plugin_message_callback(3, "fatal: %s", "out of memory");
    check("fatal level", 3, "fatal: out of memory");

    /* Test 6: format string with no specifiers (safe, no args) */
    wild_plugin_message_callback(0, "no specifiers here");
    check("no specifiers", 0, "no specifiers here");

    printf("\n%d passed, %d failed\n", passed, failed);
    return failed > 0 ? 1 : 0;
}

Test that can be used to verify the variadic handling

@davidlattimore davidlattimore merged commit 9d560d7 into wild-linker:main Mar 28, 2026
24 checks passed
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.

2 participants