UNIX環境高級編程——學習筆記(1)

10.15節的實例程序
對應書中的源碼爲~/apue.3e/signals/mask.c
自己編譯出的程序和書中的輸出怎麼也對應不上.

  • 編譯:

$ cd ~/apue.3e/signals
$ gcc -o mask_d mask.c -I../include ../lib/error.o ../lib/prmask.o

運行結果:

$ ./mask_d &
[6] 24152
starting main:
$ kill -USR1 24152
starting sig_usr1:
in sig_alrm:
finishing sig_usr1:
ending main:

正確結果:

$ ./mask_d &
[6] 24152
starting main:
$ kill -USR1 `ps aux | grep mask_d | grep -v grep | awk ‘{print $2}’`
starting sig_usr1: SIGUSR1
in sig_alrm: SIGUSR1 SIGALRM
finishing sig_usr1: SIGUSR1
ending main:

明顯沒有對任何信號進行屏蔽。
經過調試,發現:

__sysv_signal (sig=10, handler=0x400b42 ) at ../sysdeps/posix/sysv_signal.c:41

調用的是系統的api。
應該是編譯的時候沒有指定書中提供的signal實現。

  • 修改編譯命令:

$ gcc -o mask_d mask.c -I../include ../lib/error.o ../lib/prmask.o ../lib/signal.o

運行程序還是不行,效果一樣的。
經gdbtui調試調用的還是__sysv_signal。
使用readelf查看mask_d:

$ readelf mask_d -a | grep signal
000000601b40 000100000007 R_X86_64_JUMP_SLO 0000000000000000 __sysv_signal + 0
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __sysv_signal@GLIBC_2.2.5 (2)
27: 0000000000401484 149 FUNC GLOBAL DEFAULT 13 signal
56: 0000000000000000 0 FILE LOCAL DEFAULT ABS signal.c
63: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __sysv_signal@@GLIBC_2.2.
104: 0000000000401484 149 FUNC GLOBAL DEFAULT 13 signal

符號表有signal,但是調用的還是系統的__sysv_signal,重定位段.rela.plt有__sysv_signal的重定位信息。
既然沒調用signal,爲什麼會有signal的符號表,連接的時候難道不優化掉嗎???

(gdb) info address signal
Symbol “signal” is a function at address 0x401484.
(gdb) x/i 0x401484
0x401484 < signal> : push %rbp
(gdb) disassemble signal
Dump of assembler code for function signal:
0x0000000000401484 <+0>: push %rbp
0x0000000000401485 <+1>: mov %rsp,%rbp
0x0000000000401488 <+4>: sub $0x150,%rsp
0x000000000040148f <+11>: mov %edi,-0x144(%rbp)


  • 再次修改:

$ gcc -I../include -g mask.c -o mask_d -L../lib -lapue
運行readelf:
$ readelf mask_d -a | grep signal
0000006019c8 000100000007 R_X86_64_JUMP_SLO 0000000000000000 __sysv_signal + 0
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __sysv_signal@GLIBC_2.2.5 (2)
62: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __sysv_signal@@GLIBC_2.2.

signal符號與實現沒有了。
看來以後一些庫函數,能把它放到靜態庫裏,就儘量放到靜態庫裏,編譯器會根據使用情況,對最終的二進制執行文件進行優化的。

查找源碼中的Makefile,發現Make.defines.linux中定義的

CFLAGS=-ansi -I$(ROOT)/include -Wall -DLINUX -D_GNU_SOURCE -g $(EXTRA)

挨個添加選項最後發現,原來是_GNU_SOURCE搞的鬼。

$ gcc -I../include -g mask.c -o mask_d -L../lib -lapue -D_GNU_SOURCE
26: 0000000000401444 149 FUNC GLOBAL DEFAULT 13 signal
56: 0000000000000000 0 FILE LOCAL DEFAULT ABS signal.c
103: 0000000000401444 149 FUNC GLOBAL DEFAULT 13 signal

一切正常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章