printf functions don't format
I am having a hard time tracking down exactly what the issue is, but it's easy to repro
#include <stdio.h>
char buf[0x10];
int main (void)
{
// Prefill the buffer to show there IS a write
buf[0] = 0x41;
buf[1] = 0x41;
buf[2] = 0x41;
buf[3] = 0x41;
buf[4] = 0x41;
sprintf(buf, "aa%02X", 0x34);
}
avr-gcc -mmcu=atmega328 -Wall -Os -o blink3.elf blink.c
This should yield 61 61 33 34 00 in memory, but instead you get 00 41 41 41 41.
0100: 00 00 00 00 00 00 00 00 00 41 41 41 41 00 00 00 .........AAAA...
(buf starts at 0x108 for me)
I think some check short circuits and the result length is determined to be 0, and it just writes a null byte there.
Seems that the behaviour is different than I thought: It doesn't even write a null byte! Testing this more closely I noticed that #524 was throwing us off, since it was causing the sprintf call to use an empty string as the format string.
Now what I see suggests that sprintf is basically doing nothing:
0100: 61 61 25 30 32 58 00 00 41 41 41 41 41 00 00 00 aa%02X..AAAAA...
Better repro:
#include <stdarg.h>
char buf[16];
static inline void out_u8(unsigned char b) {
asm volatile("out 1, %0" ::"r"(b));
}
int my_vsprintf(char *s, const char *format, va_list ap) {
va_list aq;
va_copy(aq, ap);
int x = va_arg(aq, int);
out_u8(x); // Should output 12
x = va_arg(aq, int);
out_u8(x); // Should output 34
x = va_arg(aq, int);
out_u8(x); // Should output 56
return 0;
}
int my_sprintf(char *s, const char *format, ...) {
va_list arg;
int done;
va_start(arg, format);
done = my_vsprintf(s, format, arg);
va_end(arg);
return done;
}
int main(void) {
// Prefill to show writes happen
for (int i = 0; i < 5; i++) {
buf[i] = 'A';
}
my_sprintf(buf, "aa%02X", 0x12, 0x34, 0x56, 0x78);
asm volatile("out 0, %0" ::"r"((unsigned char)0));
return 0;
}
This should output 12, 34, 56, but instead outputs 00, 00, 00
Root caused: Nothing with our stack per-se, but rather the issue was that when using va_args, it causes the compiled to emit sty_ii instructions, which were not properly implemented.