2016-12-22 1 views
1

Я хочу, чтобы вызвать системный вызов записи с 32-битной сборки, код им с помощью прямо сейчас:Смешанное число и строка на выходе Трассирование в записи системного вызова

.section .rodata    # read-only data 
msg: 
    .ascii "hello"    # not null-terminated string called "msg" 
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 

Он собирает и работает правильно, печатая строку " привет»на консоль, но когда я использую Трассирование, чтобы„видеть“запись происходит, я получаю следующий результат:

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 +++ 

Я хотел бы знать, что вызывает третий arugment быть 5hello вместо 5.

+2

Ничего, 'hello' в нем есть фактический результат вашей программы. Переадресовывайте вывод либо strace, либо вашего кода, чтобы они не перемещались. – Jester

ответ

2

Ничего, hello есть фактический вывод вашей программы. Вот что происходит:

  1. Трассирование перехватывает от записи SYSCALL
  2. Strace печатает имя вызова и аргументы: write(1, "hello", 5. Обратите внимание: stderr. По какой-то причине он еще не печатает закрытие .
  3. write syscall получает исполнение, поэтому hello напечатан на stdout.
  4. Теперь strace должен получить контроль, чтобы он мог напечатать возвращаемое значение, которое он делает вместе с закрывающей скобкой, давая ) = 5.

В вашем случае оба stdout и stderr относятся к тому же терминалу. Переадресовывайте вывод либо strace, либо вашего кода, чтобы они не перемещались.

+0

Я не могу поверить, что я пропустил это, спасибо. я приму ваш ответ за 3 минуты – Maciej

+0

Я считаю, что крюк 'strace' выведет аргументы перед вызовом системного вызова (логически, так как звонок может свободно их модифицировать), а затем по возвращении он заканчивает вывод с помощью возвращаемое значение. Между тем, написала, что это работа с «привет». – Ped7g

+0

@ Ped7g: Это не полностью объясняет, почему 'strace' не ждет печати') = retval'. Причина в том, что системные вызовы могут блокироваться, поэтому он печатает материал вызова перед вызовом и возвращаемый материал после вызова. Это легко увидеть, запустив 'strace sleep 1'. strace будет даже печатать лишние вещи, когда системный вызов прерывается сигналом (например, если вы '^ z' во время' nanosleep' или 'pkill -WINCH sleep' посылаете ему сигнал, который ничего не сделает). –

Смежные вопросы