linux -/proc/<pid>/stat 的“eip”字段似乎没有更新

标签 linux bash proc

根据这个线程,/proc//stat 的第 30 个值(从 1 开始)应该显示进程的 'eip' 值。

Get instruction pointer of running application on Unix

但是当我打印出 bash 进程的第 30 个值时,它一直返回相同的地址:

root@graphics:/proc# ps | grep bash
 3032 pts/21   00:00:00 bash
root@graphics:/proc# cd 3032
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a
root@graphics:/proc/3032# cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f53790ef84a

chrome 也是如此。我认为“eip”值在执行时会不断动态变化。为什么它总是返回相同的地址?


好吧,看完明杰的回答,我下定决心,如果我超频繁地检查,这个值是否真的改变了。目标进程是 chrome,它的 pid 是 1834。这是我的 bash 脚本,用于代表我检查该值:

#!/bin/bash

EIP=
while true; do
    NEW_EIP=`cat /proc/1834/stat | awk '{print $30}' | xargs printf "0x%x"`
    if [[ "$NEW_EIP" != "$EIP" ]]; then
        echo "eip changed! (eip: " $NEW_EIP ")"
    fi

    EIP=$NEW_EIP
    echo $EIP >> $0.dump
done

如果捕获的第 30 个值与先前捕获的值不同,该脚本旨在打印 eip changed! 消息。当我运行这个脚本时,事实证明它实际上正在发生变化!

root@graphics:/home/gwangmu/Documents# ./eiptest 
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94e868ce0d )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94e868ce0d )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94e868cbfa )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94e868ce0d )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94e868d23d )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94e868d23d )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94e868ce0d )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94ee983c7a )
eip changed! (eip:  0x7f94e711e8dd )
eip changed! (eip:  0x7f94ee7a1190 )
eip changed! (eip:  0x7f94e711e8dd )

我希望它能对其他人有所帮助。谢谢明杰!

最佳答案

bash运行程序时,会一直等到子进程退出,所以eip就是指向waitpid调用的退出地址

/proc/9919$ cat stat | awk '{print $30}' | xargs printf "0x%x" && echo
0x7f037e3a831c

你可以使用gdb检查它

% gdb
(gdb) attach 9919
Attaching to process 9919
Reading symbols from /bin/bash...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libncurses.so.5...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libtinfo.so.5...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libnss_compat.so.2...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libnsl.so.1...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libnss_nis.so.2...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libnss_files.so.2...(no debugging symbols found)...done.
0x00007f037e3ca5e0 in read () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) disassemble 0x7f037e3a831c
Dump of assembler code for function waitpid:
   0x00007f037e3a8300 <+0>: mov    0x2f14cd(%rip),%r9d        # 0x7f037e6997d4
   0x00007f037e3a8307 <+7>: test   %r9d,%r9d
   0x00007f037e3a830a <+10>:    jne    0x7f037e3a8336 <waitpid+54>
   0x00007f037e3a830c <+12>:    xor    %r10d,%r10d
   0x00007f037e3a830f <+15>:    movslq %edx,%rdx
   0x00007f037e3a8312 <+18>:    movslq %edi,%rdi
   0x00007f037e3a8315 <+21>:    mov    $0x3d,%eax
   0x00007f037e3a831a <+26>:    syscall 
   0x00007f037e3a831c <+28>:    cmp    $0xfffffffffffff000,%rax
   0x00007f037e3a8322 <+34>:    ja     0x7f037e3a8325 <waitpid+37>
   0x00007f037e3a8324 <+36>:    retq   
   0x00007f037e3a8325 <+37>:    mov    0x2ebb3c(%rip),%rdx        # 0x7f037e693e68
   0x00007f037e3a832c <+44>:    neg    %eax
   0x00007f037e3a832e <+46>:    mov    %eax,%fs:(%rdx)
   0x00007f037e3a8331 <+49>:    or     $0xffffffffffffffff,%rax
   0x00007f037e3a8335 <+53>:    retq   
   0x00007f037e3a8336 <+54>:    push   %rbx
   0x00007f037e3a8337 <+55>:    sub    $0x10,%rsp
   0x00007f037e3a833b <+59>:    mov    %edx,0xc(%rsp)
   0x00007f037e3a833f <+63>:    mov    %rsi,(%rsp)
   0x00007f037e3a8343 <+67>:    mov    %edi,0x8(%rsp)
   0x00007f037e3a8347 <+71>:    callq  0x7f037e3e3620
   0x00007f037e3a834c <+76>:    mov    $0x3d,%ecx
   0x00007f037e3a8351 <+81>:    mov    %eax,%r8d
   0x00007f037e3a8354 <+84>:    xor    %r10d,%r10d
   0x00007f037e3a8357 <+87>:    movslq 0xc(%rsp),%rdx
   0x00007f037e3a835c <+92>:    mov    (%rsp),%rsi
   0x00007f037e3a8360 <+96>:    mov    %ecx,%eax
   0x00007f037e3a8362 <+98>:    movslq 0x8(%rsp),%rdi
   0x00007f037e3a8367 <+103>:   syscall 
   0x00007f037e3a8369 <+105>:   cmp    $0xfffffffffffff000,%rax
   0x00007f037e3a836f <+111>:   mov    %rax,%rbx
   0x00007f037e3a8372 <+114>:   ja     0x7f037e3a8384 <waitpid+132>
   0x00007f037e3a8374 <+116>:   mov    %r8d,%edi
   0x00007f037e3a8377 <+119>:   callq  0x7f037e3e3680
   0x00007f037e3a837c <+124>:   add    $0x10,%rsp
   0x00007f037e3a8380 <+128>:   mov    %ebx,%eax
   0x00007f037e3a8382 <+130>:   pop    %rbx
   0x00007f037e3a8383 <+131>:   retq   
   0x00007f037e3a8384 <+132>:   mov    0x2ebadd(%rip),%rax        # 0x7f037e693e68
   0x00007f037e3a838b <+139>:   neg    %ebx
   0x00007f037e3a838d <+141>:   mov    %ebx,%fs:(%rax)
   0x00007f037e3a8390 <+144>:   or     $0xffffffffffffffff,%rbx
   0x00007f037e3a8394 <+148>:   jmp    0x7f037e3a8374 <waitpid+116>
End of assembler dump.

0x7f037e3a831c 在函数 waitpid

中的系统调用之后

关于linux -/proc/<pid>/stat 的“eip”字段似乎没有更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33035178/

相关文章:

sas proc 导出错误

ruby - 如何使用带参数的 lambda 来收集数组?

linux - 复制一个 1TB 的稀疏文件

c - #include – 从 <> 切换到 ""后构建失败

linux - 在 Bash/Awk/Perl 中有效地按列计算 token

python - 将Python文件作为linux命令执行

linux - 两个 open/proc 条目的处理方式不同

java - 如何将重复调用的外部进程集成到Java webapp中?

linux 将路径附加到 secure_path 以使用 sudo 运行 pyenv

linux - 将文本附加到文件中的多行的每一行