架构自定义UDP协议视频传输调试
一、整体系统架构图┌─────────────────────────────────────────────────────────────────┐ │ 视频流应用程序 │ │ test_stream │ └─────────────────────────────────────────────────────────────────┘ │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 发送端模块 │ │ 接收端模块 │ │ 双工模块 │ │ STREAM_ROLE_ │ │ STREAM_ROLE_ │ │ STREAM_ROLE_ │ │ SENDER │ │ RECEIVER │ │ DUPLEX │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ StreamContext │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 网络模块 │ │ RTP模块 │ │ 抖动缓冲 │ │ 帧队列 │ │ │ │ UDPContext │ │ RTPPacket │ │JitterBuffer │ │ FrameQueue │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 调试工具模块 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 日志系统 │ │性能计数器 │ │ 内存跟踪 │ │ 网络分析 │ │ │ │ debug_log │ │perf_counter │ │memory_trace │ │packet_capture│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────────┘二、模块详细流程图2.1 发送端数据流程图┌─────────────────────────────────────────────────────────────────┐ │ 发送端数据流 │ └─────────────────────────────────────────────────────────────────┘ 应用层 ┌──────────────┐ │ 视频帧数据 │ (H264 NAL单元) └──────┬───────┘ │ stream_send_frame() ▼ ┌─────────────────────────────────────────────────────────────────┐ │ StreamContext (发送端) │ ├─────────────────────────────────────────────────────────────────┤ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ stream_process_send_frame() │ │ │ │ ┌─────────────┐ │ │ │ │ │ 创建H264NALU │ │ │ │ │ └──────┬──────┘ │ │ │ │ ▼ │ │ │ │ ┌─────────────────┐ │ │ │ │ │rtp_from_h264_ │ ┌─────────────────┐ │ │ │ │ │nalu() │─▶│ 单NAL单元模式 │ │ │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │rtp_from_h264_ │─▶│ FU-A分片模式 │ │ │ │ │ │nalu() │ └─────────────────┘ │ │ │ │ └─────────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────┐ │ │ │ │ │ RTPPacket数组 │ [packet0, packet1, ...] │ │ │ │ └──────┬──────┬───┘ │ │ │ │ │ │ │ │ │ │ ▼ ▼ │ │ │ │ ┌─────────────────┐ │ │ │ │ │设置RTP头部 │ sequence timestamp ssrc │ │ │ │ └──────┬──────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────┐ │ │ │ │ │rtp_packet_ │ serialize RTP包到缓冲区 │ │ │ │ │serialize() │ │ │ │ │ └──────┬──────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────┐ │ │ │ │ │ udp_send() │ ────┐ │ │ │ │ └─────────────────┘ │ │ │ │ └────────────────────────────┼──────────────────────────────┘ │ └───────────────────────────────┼──────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 网络层 (UDP传输) │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────────┐ │ │ │ udp_sendto() │ │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ socket() │─▶│ sendto() │─▶│ 网络接口 │ │ │ └─────────────────┘ └─────────────────┘ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ 局域网 │ │ │ │ UDP包传输 │ │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────────────────┘2.2 接收端数据流程图┌─────────────────────────────────────────────────────────────────┐ │ 接收端数据流 │ └─────────────────────────────────────────────────────────────────┘ 网络层 ┌─────────────────────────────────────────────────────────────────┐ │ UDP网络接收 │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────────┐ │ │ │ udp_recvfrom() │ │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ NetBuffer │ (原始UDP数据) │ │ └────────┬────────┘ │ └───────────┼──────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ StreamContext (接收端) │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────────┐ │ │ │rtp_packet_ │ 解析RTP包头 │ │ │parse() │ │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │rtp_packet_clone │ 克隆RTP包用于缓冲 │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 抖动缓冲 (JitterBuffer) │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ jitter_buffer_insert() │ │ │ │ │ │ ┌─────────────┐ │ │ │ │ │ │ │查找槽位 │ │ │ │ │ │ │ └──────┬──────┘ │ │ │ │ │ │ ▼ │ │ │ │ │ │ ┌─────────────┐ │ │ │ │ │ │ │检测丢包 │ jitter_buffer_detect_loss() │ │ │ │ │ │ └──────┬──────┘ │ │ │ │ │ │ ▼ │ │ │ │ │ │ ┌─────────────┐ │ │ │ │ │ │ │插入到槽位 │ 环形缓冲区 │ │ │ │ │ │ └──────┬──────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ │ ┌──────────────────────────────────────────────┐ │ │ │ │ │ │ │ JitterBuffer环形缓冲区 │ │ │ │ │ │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ │slot0│ │slot1│ │slot2│ │... │ │slotN│ │ │ │ │ │ │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ │ │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ 帧组装 (Frame Assembly) │ │ │ │ │ │ ┌───────────────────────────────────────────────┐ │ │ │ │ │ │ │ jitter_buffer_assemble_frame() │ │ │ │ │ │ │ │ 1. 找到最早到达的包 │ │ │ │ │ │ │ │ 2. 收集同时间戳的所有包 │ │ │ │ │ │ │ │ 3. 检查帧完整性 │ │ │ │ │ │ │ │ 4. 合并所有分片 │ │ │ │ │ │ │ │ 5. 添加H264起始码 │ │ │ │ │ │ │ └───────────────────────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ 帧队列 (FrameQueue) │ │ │ │ │ │ ┌───────────────────────────────────────────────┐ │ │ │ │ │ │ │ frame_queue_push() │ │ │ │ │ │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ │帧1 │→│帧2 │→│帧3 │ (链表队列) │ │ │ │ │ │ │ │ └─────┘ └─────┘ └─────┘ │ │ │ │ │ │ │ └───────────────────────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 应用层接口 │ │ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ │ │ stream_receive_frame() │ │ │ │ │ │ frame_queue_pop() (等待帧可用) │ │ │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ │ │ stream_free_frame() (释放帧内存) │ │ │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘2.3 抖动缓冲内部状态机┌─────────────────────────────────────────────────────────────────┐ │ 抖动缓冲状态机 │ └─────────────────────────────────────────────────────────────────┘ 包到达 │ ▼ ┌─────────────────────────────────────┐ │ jitter_buffer_insert() │ └─────────────────────────────────────┘ │ ▼ ┌─────────────────────────┐ │ 查找插入位置 │ │ find_slot() │ └─────────────────────────┘ │ ▼ ┌─────────────────────────┐ │ 检测丢包 │ │ detect_loss() │ └─────────────────────────┘ │ ▼ ┌─────────────────────────┐ │ 插入环形缓冲区 │ │ insert_at() │ └─────────────────────────┘ │ ▼ ┌─────────────────────────┐ │ 更新统计信息 │ │ update_stats() │ └─────────────────────────┘ │ ▼ ┌─────────────────────────┐ │ 自适应延迟调整 │ │ update_delay() │ └─────────────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ 定时检查帧完整性 │ └─────────────────────────────────┘ │ ┌───────────┴───────────┐ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ 帧完整 │ │ 帧不完整 │ │ frame_complete │ │ frame_incomplete│ └────────┬────────┘ └────────┬────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ 组装帧 │ │ 等待更多包 │ │ assemble_frame │ │ wait_for_packets│ └────────┬────────┘ └─────────────────┘ │ │ ▼ │ ┌─────────────────┐ │ │ 放入帧队列 │ │ │ frame_queue │ │ └─────────────────┘ │ │ │ └───────────────────────┘ │ ▼ ┌─────────────────────────┐ │ 清理过期包 │ │ clean_old() │ └─────────────────────────┘2.4 线程模型流程图┌─────────────────────────────────────────────────────────────────┐ │ 多线程协作模型 │ └─────────────────────────────────────────────────────────────────┘ 主线程 (Main Thread) ┌─────────────────────────────────────────────────────────────────┐ │ stream_create() → 初始化各个模块 │ │ stream_start() → 创建工作线程 │ │ │ │ │ ├──→ 创建发送线程 (Send Thread) │ │ ├──→ 创建接收线程 (Receive Thread) │ │ └──→ 创建统计线程 (Stats Thread) │ │ │ │ stream_stop() → 停止工作线程 │ │ stream_destroy() → 清理资源 │ └─────────────────────────────────────────────────────────────────┘ 发送线程 (Send Thread) ┌─────────────────────────────────────────────────────────────────┐ │ while(threads_running) { │ │ pthread_mutex_lock(thread_mutex); │ │ if (state PAUSED) │ │ pthread_cond_wait(thread_cond); │ │ pthread_mutex_unlock(thread_mutex); │ │ │ │ /* 等待帧数据从应用层来 */ │ │ /* 实际发送由stream_send_frame()触发 */ │ │ usleep(10000); /* 10ms心跳 */ │ │ } │ └─────────────────────────────────────────────────────────────────┘ 接收线程 (Receive Thread) ┌─────────────────────────────────────────────────────────────────┐ │ while(threads_running) { │ │ /* 检查暂停状态 */ │ │ pthread_mutex_lock(thread_mutex); │ │ if (state PAUSED) │ │ pthread_cond_wait(thread_cond); │ │ pthread_mutex_unlock(thread_mutex); │ │ │ │ /* 接收UDP数据 */ │ │ udp_recvfrom() ───────────────────────────────────┐ │ │ │ │ │ │ ▼ │ │ │ rtp_packet_parse() │ │ │ │ │ │ │ ▼ │ │ │ jitter_buffer_insert() ─────────────────────────┐ │ │ │ │ │ │ │ │ ▼ │ │ │ │ jitter_buffer_read_frame() ──────────────────┐ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ frame_queue_push() │ │ │ │ │ │ │ │ │ │ │ └──────────────────────────────────────────┼──┼───────────┘ │ │ │ │ /* 循环直到没有更多完整帧 */ │ │ │ } │ │ └─────────────────────────────────────────────────────┼──┼───────────┘ │ │ 统计线程 (Stats Thread) │ │ ┌─────────────────────────────────────────────────────┼──┼───────────┐ │ while(threads_running) { │ │ │ │ sleep(1); /* 每秒更新 */ │ │ │ │ │ │ │ │ pthread_mutex_lock(stats_mutex); │ │ │ │ /* 计算码率 */ │ │ │ │ bitrate (bytes_diff * 8) / elapsed; │ │ │ │ │ │ │ │ /* 获取抖动缓冲统计 */ │ │ │ │ jitter_buffer_get_stats() ──────────────────────┘ │ │ │ │ │ │ /* 更新统计信息 */ │ │ │ pthread_mutex_unlock(stats_mutex); │ │ │ │ │ │ /* 可选打印统计信息 */ │ │ │ stream_dump_info(); │ │ │ } │ │ └──────────────────────────────────────────────────────────┼────────────┘ │ 应用线程 (Application Thread) │ ┌──────────────────────────────────────────────────────────┼────────────┐ │ /* 发送端调用 */ │ │ │ stream_send_frame() ─────────────────────────────────────┘ │ │ │ │ │ └──→ 触发发送线程处理 │ │ │ │ /* 接收端调用 */ │ │ stream_receive_frame() ───────────────────────────────────────────┐ │ │ │ │ │ │ └──→ frame_queue_pop() (可能阻塞等待帧) │ │ │ │ │ │ stream_free_frame() (释放帧内存) │ │ └────────────────────────────────────────────────────────────────────┼─┘ │ 调试线程 (可选) │ ┌────────────────────────────────────────────────────────────────────┼─┐ │ debug_thread() { │ │ │ while(1) { │ │ │ /* 定期检查内存泄漏 */ │ │ │ debug_check_leaks(); │ │ │ │ │ │ /* 收集性能数据 */ │ │ │ perf_counter_print_all(); │ │ │ │ │ │ sleep(60); /* 每分钟检查一次 */ │ │ │ } │ │ │ } │ │ └────────────────────────────────────────────────────────────────────┴─┘2.5 内存管理流程图┌─────────────────────────────────────────────────────────────────┐ │ 内存管理策略 │ └─────────────────────────────────────────────────────────────────┘ 连续内存分配 (Contiguous) ┌─────────────────────────────────────────────────────────────────┐ │ [内存池起始] │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ MemHeader │ 数据块 │ MemHeader │ 数据块 │ MemHeader │ ... │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↑ ↑ ↑ ↑ │ │ 空闲链表头 已使用块 空闲块 已使用块 │ └─────────────────────────────────────────────────────────────────┘ 分散内存分配 (Scattered) ┌─────────────────────────────────────────────────────────────────┐ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 块1 │ │ 块2 │ │ 块3 │ │ 块4 │ (不连续) │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ │ │ │ └────────────┼────────────┼────────────┘ │ │ │ │ │ │ ┌─────▼────────────▼─────┐ │ │ │ 内存池管理链表 │ │ │ └────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ 内存池操作流程 ┌─────────────────────────────────────────────────────────────────┐ │ memory_pool_alloc() │ │ │ │ 开始 ──────────────────────────────────────────────────────┐ │ │ │ │ │ │ ▼ │ │ │ 加锁 (pthread_mutex_lock) │ │ │ │ │ │ │ ▼ │ │ │ 遍历空闲链表 ──→ 找到第一个大小足够的块 ──→ 是否找到 │ │ │ │ │ │ │ │ │ │ │ ├─否→ 解锁 │ │ │ │ │ │ 返回NULL │ │ │ │ │ ▼ │ │ │ │ └─是→ 检查块大小 │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ 是否需要分割 │ │ │ │ │ │ │ │ │ │ │ ├─否→ 标记为已使用│ │ │ │ │ │ 更新统计 │ │ │ │ │ ▼ │ │ │ │ └─是→ 分割块 │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ 创建新空闲块 │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ 标记当前块为已使用 │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ 更新空闲链表 │ │ │ │ │ │ │ │ └────────────────────────────────────────────┼──────────────┘ │ │ │ │ │ ▼ │ │ 解锁 │ │ │ │ │ ▼ │ │ 返回数据指针 │ │ │ │ │ ▼ │ │ 结束 │ └─────────────────────────────────────────────────────────────────┘2.6 函数调用关系图┌─────────────────────────────────────────────────────────────────┐ │ 顶层函数调用关系 │ └─────────────────────────────────────────────────────────────────┘ main() / test_stream ├── network_init() ├── debug_init() ├── stream_create() │ ├── udp_create() │ │ ├── socket() │ │ ├── setsockopt() │ │ └── bind() │ ├── jitter_buffer_create() │ │ └── calloc() │ └── frame_queue_create() │ ├── pthread_mutex_init() │ └── pthread_cond_init() │ ├── stream_start() │ ├── pthread_create() → stream_send_thread │ ├── pthread_create() → stream_recv_thread │ └── pthread_create() → stream_stats_thread │ ├── stream_send_frame() │ └── stream_process_send_frame() │ ├── rtp_from_h264_nalu() │ │ ├── rtp_pack_single_nalu() │ │ └── rtp_pack_fu_a() │ ├── rtp_packet_serialize() │ └── udp_send() │ └── udp_sendto() │ └── sendto() │ ├── stream_receive_frame() │ └── frame_queue_pop() │ ├── pthread_mutex_lock() │ ├── pthread_cond_wait() │ └── pthread_mutex_unlock() │ ├── stream_stop() │ ├── pthread_join() │ └── pthread_cond_broadcast() │ └── stream_destroy() ├── udp_destroy() │ └── close() ├── jitter_buffer_destroy() ├── frame_queue_destroy() └── free() 接收线程函数调用链: stream_recv_thread() ├── udp_recvfrom() │ └── recvfrom() ├── rtp_packet_parse() ├── rtp_packet_clone() ├── jitter_buffer_insert() │ ├── jitter_buffer_find_slot() │ ├── jitter_buffer_detect_loss() │ └── jitter_buffer_insert_at() ├── jitter_buffer_read_frame() │ └── jitter_buffer_assemble_frame() └── frame_queue_push() 统计线程函数调用链: stream_stats_thread() ├── jitter_buffer_get_stats() ├── stream_dump_info() └── perf_counter_print_all() └── debug_log() 调试函数调用链: debug_log() ├── get_timestamp_str() ├── get_thread_id() ├── vfprintf() → stderr └── fprintf() → log file debug_malloc() ├── malloc() └── debug_memory_alloc() ├── backtrace() └── debug_log()2.7 数据包处理流程┌─────────────────────────────────────────────────────────────────┐ │ RTP数据包处理流程 │ └─────────────────────────────────────────────────────────────────┘ 发送方向 (从左到右): ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ H264帧 │───▶│NAL单元 │───▶│RTP包 │───▶│UDP数据报│───▶ 网络 └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ ▼ ▼ ▼ NAL类型: RTP头部: UDP头部: - SPS/PPS - Version2 - 源端口 - IDR帧 - Payload Type - 目的端口 - P帧 - Sequence - 长度 - FU-A分片 - Timestamp - 校验和 - SSRC 接收方向 (从右到左): ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ 网络 │───▶│UDP数据报│───▶│RTP包 │───▶│NAL单元 │───▶│H264帧 │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ ▼ ▼ ▼ ▼ UDP解包 RTP解析 NAL重组 帧组装 - 检查版本 - FU-A合并 - 添加起始码 - 验证SSRC - STAP-A拆分 - 时间戳管理 - 序列号处理 - NAL类型识别 - 关键帧检测 RTP包格式: ┌─────────────────────────────────────────────────────────────┐ │ 0 1 2 3│ │ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1│ ├─────────────────────────────────────────────────────────────┤ │V2|P|X| CC |M| PT | sequence number │ ├─────────────────────────────────────────────────────────────┤ │ timestamp │ ├─────────────────────────────────────────────────────────────┤ │ synchronization source (SSRC) │ ├─────────────────────────────────────────────────────────────┤ │ contributing sources (CSRC) (optional) │ ├─────────────────────────────────────────────────────────────┤ │ payload data ... │ └─────────────────────────────────────────────────────────────┘2.8 调试工具架构┌─────────────────────────────────────────────────────────────────┐ │ 调试工具架构 │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ DebugContext │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 配置: global_level, module_levels, enable_color, ... │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ 性能计数器数组: │ │ │ │ [0] nameudp_send, typeTIMER, count100, total... │ │ │ │ [1] namertp_parse, typeTIMER, count50, total... │ │ │ │ [2] namepacket_loss, typeCOUNTER, value5 │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ 内存跟踪链表: │ │ │ │ ptr0x1234, size1024, filetest.c, line42 │ │ │ │ ptr0x5678, size2048, filejitter.c, line100 │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ 统计信息: │ │ │ │ log_messages1000, errors5, warnings10 │ │ │ │ current_memory10240, peak_memory20480 │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ 日志系统流程图: ┌─────────────────────────────────────────────────────────────────┐ │ debug_log() │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 1. 检查日志级别是否启用 │ │ │ │ if (level module_level) return; │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 2. 获取时间戳和线程ID │ │ │ │ get_timestamp_str() │ │ │ │ get_thread_id() │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 3. 格式化日志消息 │ │ │ │ vsnprintf() │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 4. 输出到控制台带颜色 │ │ │ │ fprintf(stderr, %s%s%s, color, buffer, reset) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 5. 输出到日志文件 │ │ │ │ if (log_file) fprintf(log_file, buffer) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 6. 更新统计信息 │ │ │ │ stats.log_messages │ │ │ │ if (level ERROR) stats.errors │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ 性能计数器工作流程: ┌─────────────────────────────────────────────────────────────────┐ │ perf_counter_start() perf_counter_end() │ │ │ │ │ │ ▼ ▼ │ │ clock_gettime() clock_gettime() │ │ │ │ │ │ │ ▼ │ │ └─────────────────→ 计算时间差 │ │ │ │ │ ▼ │ │ 更新计数器: │ │ count │ │ total elapsed │ │ if (elapsed min) min elapsed │ │ if (elapsed max) max elapsed │ │ avg total / count │ │ │ └─────────────────────────────────────────────────────────────────┘ 内存跟踪工作流程: ┌─────────────────────────────────────────────────────────────────┐ │ debug_malloc(size) debug_free(ptr) │ │ │ │ │ │ ▼ ▼ │ │ ptr malloc(size) debug_memory_free(ptr) │ │ │ │ │ │ ▼ ▼ │ │ debug_memory_alloc() 在链表中查找对应记录 │ │ │ │ │ │ ▼ ▼ │ │ 创建MemoryTrace记录 标记为freed │ │ │ │ │ │ ▼ ▼ │ │ 记录调用回溯 更新统计: │ │ backtrace() total_freed size │ │ current_memory - size │ │ free_count │ │ free(ptr) │ └─────────────────────────────────────────────────────────────────┘
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2418934.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!