乐于分享
好东西不私藏

libev库源码分析系列教程(三)

libev库源码分析系列教程(三)

源码分析mettle后门工具学习 所使用的依赖库

官网:http://securitytech.cc

libev 源码深度解析

1. 核心源码文件结构

1.1 主要源文件功能划分

libev-4.33/├── ev.h              # 核心API声明和基础数据结构├── ev.c              # 核心实现和主事件循环逻辑├── ev_vars.h         # 全局变量声明宏定义├── ev_wrap.h         # 多实例支持包装器├── ev++.h            # C++绑定接口├── event.h           # libevent兼容API├── ev_select.c       # select后端实现├── ev_poll.c         # poll后端实现├── ev_epoll.c        # epoll后端实现 (Linux)├── ev_kqueue.c       # kqueue后端实现 (BSD)├── ev_port.c         # event ports后端实现 (Solaris)└── ev_win32.c        # Windows平台实现

2. 核心数据结构源码分析

2.1 Watcher基础结构实现

ev.h中的核心定义

/* Watcher基础宏定义 */#defineEV_WATCHER(type)                        \   int active;     /* active状态: 0=未激活, 1+=优先级+1 */ \  intpending;    /* pending计数: 0=无pending, 1+=pending队列位置 */ \  intpriority;   /* 优先级: 0=最高, NUMPRI-1=最低 */ \  void*data;     /* 用户自定义数据指针 */ \  structev_watcher*next/* 双向链表指针 */ \  structev_watcher*prev;/* 时间相关Watcher扩展 */#defineEV_WATCHER_TIME(type)                   \   EV_WATCHER(type)                              \   ev_tstamp at;     /* 绝对超时时间 *//* 具体Watcher类型定义 */typedefstruct{  EV_WATCHER(ev_io)  intfd;           /* 文件描述符 */intevents;       /* 监听事件(POLLIN/POLLOUT等) */ev_io;typedefstruct{  EV_WATCHER_TIME(ev_timer)  ev_tstamprepeat/* 重复间隔(0=一次性) */ev_timer;

2.2 事件循环结构详解

ev_loop的内存布局 (ev_vars.h)

/* 核心变量宏定义系统 */#defineVAR(type,name,init,destructor,value) \   type name;/* 实际结构体生成 */structev_loop{  #include "ev_vars.h"  /* 展开所有变量定义 */};/* 关键字段分析 */VAR(intbackend_fd, , , 0)                    // 后端文件描述符VAR(ev_tstampnow_floor, , , 0.)              // 当前时间缓存VAR(intpendingpri, , , 0)                    // 当前处理的pending优先级VAR(ev_watcher*pending, [NUMPRI], , 0)      // pending队列数组VAR(ev_watcher_list*anfds, , , 0)           // fd到watcher映射表

3. 核心算法实现源码

3.1 时间堆算法实现

最小堆操作函数 (ev.c)

/* 堆上浮操作 */inline_sizevoidupheap (ANHE*heapintpriintk) {  ANHEhe=heap [k];  while (k>HEAP0&&ANHE_at (he<ANHE_at (heap [HPARENT (k)]))     {      heap [k=heap [HPARENT (k)];      ev_active (ANHE_w (heap [k])) =k--;     }  heap [k=he;  ev_active (ANHE_w (he)) =k; }/* 堆下沉操作 */inline_sizevoiddownheap (ANHE*heapintpriintk) {  ANHEhe=heap [k];  for (;;)     {      intc=HEAP0+ (k-HEAP0*2;      if (c >= (HEAP0+timercnt [pri]))        break;      c+=c+1< (HEAP0+timercnt [pri])             &&ANHE_at (heap [c]) >ANHE_at (heap [c+1]);      if (ANHE_at (he) <= ANHE_at (heap [c]))        break;      heap [k=heap [c];      ev_active (ANHE_w (heap [k])) =k;      k=c;     }  heap [k=he;  ev_active (ANHE_w (he)) =k; }

3.2 事件分发核心逻辑

主事件循环实现 (ev.c)

// 核心事件处理函数intev_run (EV_P_intflags) {  ++loop_depth;     while (ecb_expect_true (activecnt||loop_done||pendingcnt))     {      if (ecb_expect_false (loop_done))        break;      /* 阶段1: prepare watchers */EV_INVOKE_PENDING;  // 处理pending事件if (ecb_expect_false (pendingcnt<0))        pendingcnt=0;      /* 阶段2: 调度计算 */ev_tstamptimeout=0.;      if (ecb_expect_true (!(flags&EVRUN_NOWAIT||idleall|| !activecnt)))         {          timeout=MAX_BLOCKING_INTERVAL;                     if (timercnt [LOW])             {              ev_tstampto=ANHE_at (timerv [LOW][HEAP0]) -ev_rt_now;              if (to<timeout)                timeout=to;             }         }      /* 阶段3: backend轮询 */backend_poll (EV_A_timeout);      /* 阶段4: 处理就绪事件 */EV_INVOKE_PENDING;      /* 阶段5: check watchers */     }  --loop_depth;  returnactivecnt; }

4. Backend后端实现分析

4.1 epoll后端源码 (ev_epoll.c)

初始化函数

staticvoidepoll_init (EV_P_intflags) {  if (!epoll_eventmax)    epoll_eventmax=64;  epoll_events= (structepoll_event*)ev_malloc (sizeof (structepoll_event*epoll_eventmax);#ifdefEPOLL_CLOEXECbackend_fd=epoll_create1 (EPOLL_CLOEXEC);  if (backend_fd<0&& (errno==EINVAL||errno==ENOSYS))#endifbackend_fd=epoll_create (epoll_eventmax);  if (backend_fd<0)    return;  fcntl (backend_fdF_SETFDFD_CLOEXEC);  fd_change (EV_A_backend_fdEV__IOFDSET);}

事件轮询实现

staticvoidepoll_poll (EV_P_ev_tstamptimeout) {  intres=epoll_wait (backend_fdepoll_eventsepoll_eventmax,                        epoll_wait_timeout (timeout));  for (inti=0i<res++i)     {      structepoll_event*e=epoll_events+i;      intfd=e->data.fd;             if (ecb_expect_true (fd >= 0&&fd<anfdmax&&anfds [fd].events))        fd_event (EV_A_fde->events);      elsepipe_write_wanted=1/* probably a pipe was closed */     } }

4.2 kqueue后端源码 (ev_kqueue.c)

kqueue特有的事件类型处理

staticvoidkqueue_poll (EV_P_ev_tstamptimeout) {  structtimespects;  ts.tv_sec= (long)timeout;  ts.tv_nsec= (long)((timeout- (long)timeout*1e9);  intres=kevent (backend_fd00kqueue_changeskqueue_changemax&ts);  for (inti=0i<res++i)     {      structkevent*kev=kqueue_events+i;      intfd=kev->ident;             if (kev->filter==EVFILT_READ)        fd_event (EV_A_fdEV_READ);      elseif (kev->filter==EVFILT_WRITE)        fd_event (EV_A_fdEV_WRITE);      elseif (kev->filter==EVFILT_SIGNAL)        ev_feed_signal_event (EV_A_kev->ident);     } }

5. 内存管理源码分析

5.1 对象池实现

内存池管理结构

/* 内存池节点定义 */structev_walk{  inttype;                      // 对象类型标识intsize;                      // 对象大小void*mem;                     // 内存块指针structev_walk*next;          // 链表指针};/* 预定义的对象池 */staticstructev_walkmempool[] = {   { EV_IOsizeof(ev_io), 00 },   { EV_TIMERsizeof(ev_timer), 00 },   { EV_PERIODICsizeof(ev_periodic), 00 },   { EV_SIGNALsizeof(ev_signal), 00 },   { EV_CHILDsizeof(ev_child), 00 },   { EV_STATsizeof(ev_stat), 00 },   { EV_IDLEsizeof(ev_idle), 00 },   { EV_PREPAREsizeof(ev_prepare), 00 },   { EV_CHECKsizeof(ev_check), 00 },   { EV_EMBEDsizeof(ev_embed), 00 },   { EV_FORKsizeof(ev_fork), 00 },   { EV_ASYNCsizeof(ev_async), 00 },   { EV_CLEANUPsizeof(ev_cleanup), 00 },   { 0000 } };

5.2 动态数组扩容机制

文件描述符数组扩容

staticvoidnoinlinearray_needsize (void*baseint*curintmaxintelement_sizevoid*(*cb)(void*baseint*curintmax)) {  if (max>*cur)     {      void*newbase=cb (basecurmax);      if (newbase)         {          memset ((char*)newbase+*cur*element_size0, (max-*cur*element_size);          *cur=max;         }     } }/* fd数组扩容回调 */staticvoid*anfds_resize (void*baseint*curintmax) {  returnev_realloc (basemax*sizeof (ev_watcher_list)); }

6. 时间管理源码详解

6.1 多时间源支持

时间获取函数实现

staticev_tstampev_time (void) {#ifEV_USE_MONOTONICif (ecb_expect_true (have_monotonic))     {      structtimespects;      clock_gettime (CLOCK_MONOTONIC&ts);      returnts.tv_sec+ts.tv_nsec*1e-9;     }#endif    {    structtimevaltv;    gettimeofday (&tv0);    returntv.tv_sec+tv.tv_usec*1e-6;   } }

6.2 定时器管理实现

定时器插入算法

staticvoidnoinlinetimers_reify (EV_P) {  EV_FREQUENT_CHECK;  while (timercnt [LOW&&ANHE_at (timerv [LOW][HEAP0]) <ev_rt_now)     {      ev_tstampat=ANHE_at (timerv [LOW][HEAP0]);      ev_watcher_time*w= (ev_watcher_time*)ANHE_w (timerv [LOW][HEAP0]);      /* 从堆中移除 */timerv [LOW][HEAP0=timerv [LOW][--timercnt [LOW]];      downheap (timerv [LOW], LOWHEAP0);      /* 设置pending状态 */ev_at (w=at;      w->pending=1;      pendings [ABSPRI (w)][w->pending-1].w= (ev_watcher*)w;      pendingpri=NUMPRI/* force recalculation */     } }

7. 跨平台适配源码

7.1 条件编译实现

平台检测和后端选择

/* ev.c中的平台适配 */#ifEV_USE_EPOLL# include"ev_epoll.c"#endif#ifEV_USE_KQUEUE# include"ev_kqueue.c"#endif#ifEV_USE_PORT# include"ev_port.c"#endif#ifEV_USE_POLL# include"ev_poll.c"#endif#ifEV_USE_SELECT# include"ev_select.c"#endif/* 默认后端选择逻辑 */staticvoid (*backend_init) (EV_P_intflags=epoll_init;staticvoid (*backend_destroy) (EV_P=epoll_destroy;staticvoid (*backend_poll) (EV_P_ev_tstamptimeout=epoll_poll;staticint (*backend_check) (EV_P=epoll_check;

7.2 系统调用封装

文件描述符操作封装

/* 跨平台fd操作 */inline_speedvoidfd_change (EV_P_intfdintflags) {  unsigned charold=anfds [fd].events;  unsigned charnew=old | flags;     if (ecb_expect_false (new!=old))     {      anfds [fd].events=new;             /* 更新backend注册 */if (old)        fd_kill (EV_A_fd);             if (new)        fd_reify (EV_A_fd);     } }

8. 调试和验证机制

8.1 数据结构完整性检查

循环不变量验证

staticvoidnoinlineecb_coldev_verify (EV_P) {  inti;  intfdchanged=0;     assert (("libev: loop not initialized"ev_is_active (&pipe_w)));  assert (("libev: loop not active"ev_active (&pipe_w==1));     /* 验证pending队列一致性 */for (i=NUMPRIi--; )     {      intj=0;      ANPENDING*p;             for (p=pendings [i]; pp= (ANPENDING*)((ev_watcher*)p)->next)         {          assert (("libev: pending watcher not on pending queue",                     pendings [ABSPRI (p->w)][p->w->pending-1].w==p->w));          assert (("libev: pending index mismatch",                     p->w->pending==j+1));          ++j;         }     }     /* 验证fd映射表 */for (i=0i<anfdmax++i)     {      ev_watcher_list*w;             for (w=anfds [i].headww=w->next)         {          assert (("libev: inactive fd watcher on anfd list",                     ev_active (w==1));          assert (("libev: fd mismatch between watcher and anfd",                     ((ev_io*)w)->fd==i));         }     } }

8.2 运行时调试输出

调试信息宏定义

/* 多级别调试输出 */#ifEV_DEBUG_LEVEL>0# defineEV_DBG(lvlfmtargs...) \     do { \         if (ev_debug_level >= lvl) \             fprintf(stderr, "[libev:%d] " fmt "\n", lvl, ##args); \     } while(0)#else# defineEV_DBG(lvlfmtargs...) do {} while(0)#endif/* 性能统计 */#ifEV_STATSVAR(unsigned intloop_count, , , 0)           // 事件循环次数VAR(unsigned intloop_depth, , , 0)           // 嵌套深度VAR(ev_tstamptimeout_block, , , 0.)          // 阻塞时间统计#endif

9. 性能优化技巧源码

9.1 分支预测优化

likely/unlikely宏应用

/* 编译器分支预测提示 */#defineecb_expect_false(expr) __builtin_expect(!!(expr), 0)#defineecb_expect_true(expr)  __builtin_expect(!!(expr), 1)/* 实际应用场景 */if (ecb_expect_true (activecnt+1<1U << (sizeof (int*8-1)))  activecnt+=1;while (ecb_expect_false (loop_done))  break;

9.2 缓存友好设计

内存访问模式优化

/* 连续内存访问优化 */staticvoidfd_reify (EV_P_intfd) {  /* 批量处理减少缓存未命中 */if (fdchangecnt)     {      /* 按顺序处理变更 */for (inti=0i<fdchangecnt++i)         {          intfd=fdchanges [i];          // ... 处理逻辑         }      fdchangecnt=0;     } }

10. 源码阅读建议

10.1 阅读顺序推荐

  1. ev.h
     – 理解API接口和数据结构
  2. ev_vars.h
     – 掌握全局状态管理
  3. ev.c
     – 学习核心事件循环实现
  4. 具体backend文件
     – 理解平台适配机制
  5. ev++.h
     – 了解C++绑定设计

10.2 关键函数追踪

ev_run() → backend_poll() → fd_event() → ev_invoke()     ↓           ↓              ↓            ↓  主循环    系统调用    事件分发    用户回调

源码版本: libev 4.33分析深度: 源码级别更新时间: 2026年3月1日

  • 公众号:安全狗的自我修养

  • vx:2207344074

  • http://gitee.com/haidragon

  • http://github.com/haidragon

  • bilibili:haidragonx

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » libev库源码分析系列教程(三)

评论 抢沙发

1 + 1 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮