Why Does Piping Output to Hexdump Fail for My Assembly printf Function?

Here is a low level debugging tool for an Intel Core i7 12700K system running Ubuntu 22.04 that requires precise control over output formatting. As part of this tool, I'm implementing a custom printf like function in assembly using NASM assembler and GNU Linker. I've encountered unexpected behavior when piping the output of my assembly printf function to hexdump . The output is displayed correctly when printed directly to the terminal, but piping it to hexdump results in no output. From printf.c , output to STDOUT:
$ ./printf
TEST
$ ./printf
TEST
Pipe to hexdump:
$ ./printf | hexdump -v -C
00000000 54 45 53 54 0a |TEST.|
00000005
$ ./printf | hexdump -v -C
00000000 54 45 53 54 0a |TEST.|
00000005
Strace:
$ strace -ttT -f -e trace="write" ./printf
17:44:33.841789 write(1, "TEST\n", 5TEST
) = 5 <0.000050>
17:44:33.842320 +++ exited with 0 +++
$ strace -ttT -f -e trace="write" ./printf
17:44:33.841789 write(1, "TEST\n", 5TEST
) = 5 <0.000050>
17:44:33.842320 +++ exited with 0 +++
From printf.nasm , output to STDOUT:
$ ./printf
TEST
$ ./printf
TEST
Pipe to hexdump - no output:
$ ./printf | hexdump -v -C
$ ./printf | hexdump -v -C
Strace:
$ strace -ttT -f -e trace="write" ./printf
17:46:00.828887 write(1, "TEST\n", 5TEST
) = 5 <0.000050>
17:46:00.829282 +++ exited with 0 +++
$ strace -ttT -f -e trace="write" ./printf
17:46:00.828887 write(1, "TEST\n", 5TEST
) = 5 <0.000050>
17:46:00.829282 +++ exited with 0 +++
Ryt now I suspect the system call interactions between C and assembly. I want to understanding the underlying reasons for this and potential solutions to ensure consistent output behavior in both C and assembly implementations
attachment 0
attachment 1
Solution:
@Marvee Amasi The issue you're encountering is due to the buffering behavior of the standard output stream (stdout). In C, the standard library handles the buffering of stdout, which ensures that the buffer is flushed when the program exits or when the buffer is full. However, when you implement printf in assembly, you're bypassing these standard library mechanisms, which can lead to different behavior, especially when piping the output. To make sure that your assembly implementation behaves consistently, you need to explicitly flush the stdout buffer. You can achieve this by using a write system call directly instead of relying on the C printf function....
Jump to solution
2 Replies
Solution
Enthernet Code
Enthernet Code4mo ago
@Marvee Amasi The issue you're encountering is due to the buffering behavior of the standard output stream (stdout). In C, the standard library handles the buffering of stdout, which ensures that the buffer is flushed when the program exits or when the buffer is full. However, when you implement printf in assembly, you're bypassing these standard library mechanisms, which can lead to different behavior, especially when piping the output. To make sure that your assembly implementation behaves consistently, you need to explicitly flush the stdout buffer. You can achieve this by using a write system call directly instead of relying on the C printf function.
Marvee Amasi
Marvee Amasi4mo ago
Of course thanks . You know someone told me the issue was that ; the exit syscall is preventing any data my C library buffered as in via printf to be properly flushed before the process terminates. Rather than me using syscall to exit, use the C library exit function. That didn't really fix it. thanks man @Enthernet Code
Want results from more Discord servers?
Add your server