I have this strangest problem. After hours and hours of debugging, I finally traced it down to this: when I have my test function test() in the same code file as my printf(const char *format, ...) function, then the pointers, arguments and values get garbled. I encountered this problem while writing the strchr() function, and reduced it to the following test function.
In one code file, I have the following:
Code: Select all
#include <stdarg.h> // va_start(), va_end(), va_arg()
#include <scrn.h> // puts()
#include <string.h> // vsprintf()
void test()
{
void * i = (void *)0xDEADBEEF;
printf("i = 0x%p\n", i);
}
long printf(const char *format, ...)
{
va_list args;
int i;
char buffer[1024];
va_start(args, format);
i = vsprintf(buffer, format, args);
va_end(args);
puts(buffer); scrn.c
return i;
}
Code: Select all
i = 0x0002E1A0
Code: Select all
i = 0xDEADBEEF
I have used this printf() function without problems for the past month, so it should work. I removed almost all code from my OS except for the GDT, IDT, IRQ, ISRS, screen and printf() code and associated functions (meaning that paging is disabled, no malloc or heap, no thread or processes or scheduling or timer or keyboard interrupts), and the problem persists. I used an older working build and put the test() function in the file containing the printf() function, and the problem persists. I move the test function OR the printf function to any other file, and the problem is solved. The problem also occurs with arguments to the test function, when the test function has any other name, when the test function returns any value. I have increased the stack to enormous sizes and the problem is still there. I really don't get it.
Here's the code from the stdarg.h file:
Code: Select all
#ifndef __STDARG_H
#define __STDARG_H
// Variable argument list.
typedef char * va_list;
#define __va_rounded_size(TYPE) \
(((sizeof(TYPE) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
#define va_start(AP, LASTARG) \
(AP = ((char *)&(LASTARG) + __va_rounded_size(LASTARG)))
void va_end(va_list);
#define va_end(AP)
#define va_arg(AP, TYPE) \
(AP += __va_rounded_size(TYPE), \
*((TYPE *)(AP - __va_rounded_size(TYPE))))
#endif // __STDARG_H