为什么gdb中的数据段寄存器总是空的?

isa*_*amu 6 gdb glibc x86-64

为什么数据段寄存器 (ds/es/fs/gs) 在 GDB 中似乎总是显示为 0x0?例如,无论我查看什么进程或线程,“info reg”似乎总是给我这样的输出:

cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
Run Code Online (Sandbox Code Playgroud)

我正在尝试调试 glibc 代码,在我正在分解的函数中看到 fs 段前缀:

(gdb) disas __lll_lock_wait
Dump of assembler code for function __lll_lock_wait:
0x000000302800e240 <+0>:     push   %r10
0x000000302800e242 <+2>:     push   %rdx
0x000000302800e243 <+3>:     xor    %r10,%r10
0x000000302800e246 <+6>:     mov    $0x2,%edx
0x000000302800e24b <+11>:    xor    $0x80,%esi
0x000000302800e251 <+17>:    and    %fs:0x48,%esi
0x000000302800e259 <+25>:    cmp    %edx,%eax
0x000000302800e25b <+27>:    jne    0x302800e264 <__lll_lock_wait+36>
0x000000302800e25d <+29>:    mov    $0xca,%eax
Run Code Online (Sandbox Code Playgroud)

我知道这就是 glibc 为 TLS 和其他重要内容引用线程的 TCB (tcbhead_t) 的方式。那么这是否意味着每个线程都需要有一个唯一的描述符条目?每个线程不应该对 fs 寄存器有一个唯一的值吗?我什至不相信 0x0 是一个有效的选择器,因为 TI(表指示器)位会指示 GDT,我认为没有有效的 0 GDT 条目。

我知道我一定遗漏了一些明显的东西,有人知道它是什么吗?

环境:CentOS 6.6,x86_64

Emp*_*ian 1

那么这是否意味着每个线程都需要有一个唯一的描述符条目?

是的。

每个线程不应该有一个唯一的 fs 寄存器值吗?

不,寄存器的值fs是相同的,但它指向的内存在每个线程中是不同的。请参阅GLIBC 源代码中的arch_prctl(2) 手册页和代码来进行设置。