控制进程可以跟踪运行时链接程序范围内发生的特定事件。这些事件包括:
运行时链接程序已经装入并重定位所有动态库,并且即将开始调用每个装入的目标文件的 .init 节。
运行时链接程序已经完成调用所有的 .init 节,并且即将会将控制权转交给主可执行文件。
已经调用运行时链接程序来装入或卸载动态库。
可以使用 sys/link.h 和 rtld_db.h 中定义的以下接口来监视这些事件:
typedef enum { RD_NONE = 0, RD_PREINIT, RD_POSTINIT, RD_DLACTIVITY } rd_event_e; /* * Ways that the event notification can take place: */ typedef enum { RD_NOTIFY_BPT, RD_NOTIFY_AUTOBPT, RD_NOTIFY_SYSCALL } rd_notify_e; /* * Information on ways that the event notification can take place: */ typedef struct rd_notify { rd_notify_e type; union { psaddr_t bptaddr; long syscallno; } u; } rd_notify_t;
以下函数可跟踪事件:
rd_err_e rd_event_enable(struct rd_agent * rdap, int onoff);
目前,由于性能原因,运行时链接程序会忽略事件禁用。控制进程应假定可以访问指定的断点,因为最后调用了此例程。
rd_err_e rd_event_addr(rd_agent_t * rdap, rd_event_e event, rd_notify_t * notify);
根据事件类型,通过调用 notify->u.syscallno 标识的运行正常的低成本系统调用或者在 notify->u.bptaddr 指定的地址执行断点可实现控制进程通知。控制进程负责跟踪系统调用或定位实际断点。
事件发生后,可以通过 rtld_db.h 中定义的此接口获取其他信息:
typedef enum { RD_NOSTATE = 0, RD_CONSISTENT, RD_ADD, RD_DELETE } rd_state_e; typedef struct rd_event_msg { rd_event_e type; union { rd_state_e state; } u; } rd_event_msg_t;
rd_state_e 值包括:
没有其他可用的状态信息。
链接映射处于稳定状态,可以对其进行检查。
正在装入动态库,链接映射未处于稳定状态。应该在达到 RD_CONSISTANT 状态之后再检查这些链接映射。
正在删除动态库,链接映射未处于稳定状态。应该在达到 RD_CONSISTANT 状态之后再检查这些链接映射。
rd_event_getmsg() 函数用于获取此事件状态信息。
下表显示了各种不同事件类型的可能状态。
RD_PREINIT |
RD_POSTINIT |
RD_DLACTIVITY |
---|---|---|
RD_NOSTATE |
RD_NOSTATE |
RD_CONSISTANT |
|
|
RD_ADD |
|
|
RD_DELETE |