您的位置:首页 > 编程语言

UNIX环境高级编程——学习笔记(1)

2015-10-23 20:03 302 查看
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

一切正常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息