分类: 嵌入式
2011-10-15 20:21:06
在事件循环机制中往往用某个文件描述符来表示事件源,GDB所关心的事件储存在该文件描述符上。GDB的事件源来源于两方面,通常是用户接口和目标程序,这两者之间是异步的,也就是说用户输入不必等待目标运行暂停。其中用户接口上事件的类型如下:
l breakpoint_create;
l breakpoint_delete;
l breakpoint_modify;
l tracepoint_create;
l tracepoint_delete;
l tracepoint_modify;
l architecture_changed;
l nr_gdb_events;
GDB传统事件机制有hooks和gdb-events,但是它们都不足够通用,在最近版本的GDB中,引入设计模式中Observer模式作为新的事件机制范型。在事件循环中,GDB会对事件进行检测,一但某个有效事件发生,它就会通过事件通知机制告诉observer,observer事先都会安排好相应的回调函数与其关联,回调函数会对该事件进行处理。
在GDB的事件循环中,主要使用了三个链表,分别是:
l gdb_notifier:被监听的文件描述符链表;
该链表中的每个元素描述了gdb关心的某个事件,在事件循环机制中,gdb是通过通知器来监听事件源的,gdb_notifier可以用poll函数和select函数来实现两种不同的通知器,具体要看gdb所运行的平台对这两个函数的支持性。GDB的两类事件源即用户接口和目标机在gdb_notifier中分别被表示成输入文件描述符和目标文件描述符。输入文件描述符通过readline库与命令行接口通信。通过统一的接口handle_file_event去唤醒与文件描述符(由于其状态变化产生的事件)相关联的处理函数。在远程目标中使用串口与远程目标机通信,串口在GDB中也被描述成文件描述符和poll/select调用。
l event queue:已发生的事件链表;
该链表中的每个元素表示的是需要处理的事件。在GDB的事件系统中,每个事件都会关联一个事件处理函数proc(),当某个文件描述符的状态变化引起事件时,proc()就会启动与该文件描述符相关联的处理函数。在gdb事件系统中,所有的事件都是通过调用async_queue_event()入队的,然后调用gdb_do_one_event()中的process_event()来处理的。
l sighandler_list:信号处理函数链表;
该链表中每个元素表示的是在程序中可能发生的异步事件的处理函数,当某个事件产生了信号,与该信号对应的信号处理函数async_signal_handler就会被加入到sighandler_list中,这些信号处理函数将由在介绍event_queue链表中提到的proc()来调用执行。信号用来表示在程序中可能发生的异步事件。async_init_singals()负责为每个信号安装相应的async_signal_handler。
总之,gdb_notifier是事件源的文件描述符链表,event_queue是与文件描述符关联的事件链表;sighandler_list是异步事件处理函数的链表。在处理事件的时候,sighandler_list中的事件优先级最高,其次是event_queue。
在事件循环中,当gdb_notifier通过监听器监听到某个文件描述符上有新的事件的时候,由gdb_wait_for_event调用create_file_event 和async_queue_event来创建对应的文件事件并将其加入事件队列中,等待process_event处理。在处理事件时,proccess_event()首先检测sighandler_list中是否有某个async_signal_handler中的标志位为ready,当readyflag被置位的时候,相应的处理函数被调用,然后再遍历event_queue,找出已经准备好的事件进行处理.