为什么strace在附加到进程时认为这个内存是未初始化的?

时间:2018-05-11 23:24:41

标签: linux memory-management assembly strace

我有一个非常简单的程序,只能在循环中调用recvfrom()。根据它的manpage,其中一个参数是指向地址长度的指针。此地址在.data部分初始化为整数值16。当我附加到已经运行的进程来跟踪它时,我注意到一些奇怪的行为,当我直接跟踪进程时(当我开始跟踪时),这种行为不存在。滚动到行尾:

# strace -x -s 10 -e trace=recvfrom ./test
recvfrom(3, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 32, 0, {sa_family=AF_INET, sin_port=htons(42134), sin_addr=inet_addr("127.0.0.1")}, [16]) = 32
recvfrom(3, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 32, 0, {sa_family=AF_INET, sin_port=htons(49442), sin_addr=inet_addr("127.0.0.1")}, [16]) = 32
recvfrom(3, ^Cstrace: Process 18909 detached
 <detached ...>
# ./test &
# strace -x -s 10 -e trace=recvfrom -p $!
strace: Process 18916 attached
recvfrom(3, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 32, 0, {sa_family=AF_INET, sin_port=htons(50906), sin_addr=inet_addr("127.0.0.1")}, [1999040176->16]) = 32
recvfrom(3, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 32, 0, {sa_family=AF_INET, sin_port=htons(52956), sin_addr=inet_addr("127.0.0.1")}, [16]) = 32
recvfrom(3, ^Cstrace: Process 18916 detached
 <detached ...>

当我直接跟踪它时,地址长度参数显示为[16],这是有道理的。毕竟,地址是指向值int的{​​{1}}的指针。但是,当我附加到进程并跟踪它时,第一个调用显示它未初始化,例如16。每次我附加时,第一次系统调用都会发生这种情况,但所有后续调用都会将其正确显示为[1999040176->16]。如果我从进程中分离并重新连接,第一个调用将显示为具有未初始化的内存。

简短说明:

  • 当我在[16]下运行时,最后一个参数会显示strace的每个[16]

  • 当我在运行时附加到它时,最后一个参数会在第一次调用recvfrom()时显示[1999040176->16]之类的内容,并在后续所有调用中显示recvfrom()

  • 如果我从中分离并再次附加,则第一次调用[16]会再次显示此奇怪行为,所有后续调用都会显示预期的recvfrom()

这不是编程问题,因为我知道程序本身是正确的。如果重要的是,这是程序(用MIPS汇编编写):

.section .text
        .global __start

__start:
        # socket
        li      $v0,4183
        li      $a0,2
        li      $a1,1
        li      $a2,0
        syscall
        sw      $v0,sockfd

        # bind
        li      $v0,4169
        lw      $a0,sockfd
        la      $a1,sockaddr_b
        li      $a2,16
        syscall

loop:
        # recvfrom
        li      $v0,4176
        lw      $a0,sockfd
        la      $a1,buffer
        li      $a2,32
        li      $a3,0
        la      $t0,sockaddr_a
        sw      $t0,16($sp)
        la      $t0,addrlen
        sw      $t0,20($sp)
        syscall

        j       loop

.section .bss
sockaddr_a:     .space  16
buffer:         .space  32
sockfd:         .space  4

.section .data
addrlen:        .int    16

.section .rodata
sockaddr_b:     .hword  2,1234,0,0

0 个答案:

没有答案