Mixed integer and string in strace output in write syscall

377 views Asked by At

I want to call a write syscall from 32-bit assembly, the code i'm using right now:

.section    .rodata             # read-only data
msg:
    .ascii  "hello"             # char array called "msg" (no null character)
len:
    .long   5                   # length of "msg"


.section    .text               # actual runnable code
.globl      _start
.type       _start, @function
_start:
    movl    $4, %eax            # syscall number into eax (4 is write)
    movl    $1, %ebx            # argument number 1 into ebx (stdout)
    movl    $msg, %ecx          # argument number 2 into ecx
    movl    len, %edx           # argument number 3 into edx
    int     $0x80
    
    movl    $1, %eax            # syscall number into eax (1 is exit)
    movl    $0, %ebx            # argument number 1 into ebx (exit code)
    int     $0x80

To compile it i first invoke the GNU assembler and then the linker:

as --32 main.s -o main.o
ld -m elf_i386 main.o -o main

It compiles and works properly, printing the string "hello" to the console, but when i use strace to "see" the write happen, i get following output:

execve("./main", ["./main"], [/* 86 vars */]) = 0
strace: [ Process PID=22529 runs in 32 bit mode. ]
write(1, "hello", 5hello)                    = 5
exit(0)                                 = ?
+++ exited with 0 +++

I'd like to know what causes the third argument to be 5hello instead of 5.

1

There are 1 answers

4
Jester On BEST ANSWER

Nothing, the hello in there is the actual output of your program. Here is what is happening:

  1. strace intercepts the write syscall
  2. strace prints the call name and the arguments: write(1, "hello", 5. Note this goes to stderr. For some reason it doesn't print the closing ) yet.
  3. the write syscall gets executed, thus hello is printed to stdout.
  4. strace again needs to get control so it can print the return value, which it does along with the closing parenthesis giving the ) = 5.

In your case both stdout and stderr refer to the same terminal. Redirect the output of either strace or your code so they don't get interspersed.