Stdout initialisation - Unix
This is a discussion on Stdout initialisation - Unix ; Hey all,
I'm writing an interposer for the C library malloc() function at the
moment, but I'm having trouble logging the malloc() calls to file.
On the first call to malloc() my program successfully intercepts the
call, creates a new ...
-
Stdout initialisation
Hey all,
I'm writing an interposer for the C library malloc() function at the
moment, but I'm having trouble logging the malloc() calls to file.
On the first call to malloc() my program successfully intercepts the
call, creates a new file for writing, uses dup2 to associate the file
with STDOUT_FILENO, but as soon as I try to printf, it segfaults.
For some reason, if I perform at least one printf command BEFORE
redirecting stdout to file, then the program works fine, but it has to
output something to console thanks to this initial printf command.
I have used the exact code in another arbitrary C program, and it
worked fine, its just screwing up in this interposer.
Anyone know why this is happening?
Thanks
Al
-
Re: Stdout initialisation
alex.w.pitt@gmail.com writes:
> I'm writing an interposer for the C library malloc() function at the
> moment, but I'm having trouble logging the malloc() calls to file.
Malloc interposers are quite tricky: there are all kinds of "order
of initialization" issues (especially with threads).
> On the first call to malloc() my program successfully intercepts the
> call, creates a new file for writing, uses dup2 to associate the file
> with STDOUT_FILENO, but as soon as I try to printf, it segfaults.
printf() is likely trying to allocate a buffer (so it can do
fully-buffered I/O to your file) using malloc().
That of course would cause infinite recursion, and you'll run out
of stack. Use debugger to examine crash stack trace, and to confirm
or disprove that theory.
You could use 'sprintf + write(2)', or setvbuf(3) to work around
this.
Just be aware that what you are doing is very non-portable; will
likely break when moved to another OS, and may break with minor
libc patches.
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
-
Re: Stdout initialisation
In alex.w.pitt@gmail.com writes:
> On the first call to malloc() my program successfully intercepts the
> call, creates a new file for writing, uses dup2 to associate the file
> with STDOUT_FILENO, but as soon as I try to printf, it segfaults.
printf() itself calls malloc.
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
-
Re: Stdout initialisation
alex.w.pitt@gmail.com writes:
>Hey all,
>
>I'm writing an interposer for the C library malloc() function at the
>moment, but I'm having trouble logging the malloc() calls to file.
>
>On the first call to malloc() my program successfully intercepts the
>call, creates a new file for writing, uses dup2 to associate the file
>with STDOUT_FILENO, but as soon as I try to printf, it segfaults.
>
>For some reason, if I perform at least one printf command BEFORE
>redirecting stdout to file, then the program works fine, but it has to
>output something to console thanks to this initial printf command.
>
>I have used the exact code in another arbitrary C program, and it
>worked fine, its just screwing up in this interposer.
>
>Anyone know why this is happening?
>
Paul described what's probably happening.
I'd suggest you use 'snprintf' instead of printf to a statically
allocated (and locked as necessary) buffer, then use write(dup2'd fd)
from your buffer.
scott
-
Re: Stdout initialisation
On May 5 2008 22:03, John Gordon wrote:
>In .. alex.w.pitt@gmail.com writes:
>
>> On the first call to malloc() my program successfully intercepts the
>> call, creates a new file for writing, uses dup2 to associate the file
>> with STDOUT_FILENO, but as soon as I try to printf, it segfaults.
>
>printf() itself calls malloc.
Even so, with GNU libc at least, which provides a malloc hook, you
can work around it.
pseudo:
static void *my_malloc(size_t x)
{
spin_lock();
__malloc_hook = orig_malloc;
printf("In an allocation!\n");
__malloc_hook = my_malloc;
spin_unlock();
return blob_of_memory;
}
int main(void)
{
orig_malloc = malloc;
__malloc_hook = my_malloc;
printf("Hello World\n");
}