windbg 调试bug

来源:互联网 发布:网路和网络 编辑:程序博客网 时间:2024/06/08 09:23

跳过前面的基础配置和pdb加载。认为你基本的调试都会

第一步:找出崩溃的线程

一般崩溃弹出对话框截取的dump都会以主线程为显示。所以要找出崩溃的线程,

~*kbn #查看所有进程,排除在等待的线程,一般某个线程在执行最后在执行某个函数时最有可能

这里写图片描述

~69s #切换当前线程

根据崩溃的地方找到代码,及出错的相关数据:

bool ff_video_callback_frame(struct ff_frame*frame, void *opaque){    if (player_source && frame&&!player_source->abort){             if (!update_sws_context(player_source, frame->frame)){            Log_Error("update_sws_context failed!\n");            return false;        }        sws_scale(player_source->sws_ctx,            (uint8_t const *const *)frame->frame->data,            frame->frame->linesize,            0,            frame->frame->height,            &player_source->sws_data,            &player_source->sws_linesize            );    ....    }}

以上是我的代码。做一个示例:

sws_scale(player_source->sws_ctx,            (uint8_t const *const *)frame->frame->data,            frame->frame->linesize,            0,            frame->frame->height,            &player_source->sws_data,            &player_source->sws_linesize            );

问题出在sws_scale函数的调用中,,传入的参数和frame、player_source 相关,
但是当使用dv和kp的时候并没有看到frame和player_source的数据,也就是说release的程序把相关的寄存器覆盖了或者优化了。如图:
这里写图片描述

所以接下来需要从反汇编中相关的寄存器找到frame和player_source的值
首先传入的参数 都存在: rcx rdx r8 r9 和rsp中
so: 先查看调用sws_scale处的汇编代码,即ub sws_scale的RetAddr

  • player_source
0:069> ub 00007ff6`c61c01c7 L20 00007ff6`c61c0191 488b17          mov     rdx,qword ptr [rdi]00007ff6`c61c0194 488b4b18        mov     rcx,qword ptr [rbx+18h] //这里对应着player_source->sws_ctx,所以rbx就存着player_source00007ff6`c61c0198 48896c2450      mov     qword ptr [rsp+50h],rbp00007ff6`c61c019d 8b426c          mov     eax,dword ptr [rdx+6Ch]00007ff6`c61c01a0 4889742458      mov     qword ptr [rsp+58h],rsi00007ff6`c61c01a5 488d6b28        lea     rbp,[rbx+28h]00007ff6`c61c01a9 48896c2430      mov     qword ptr [rsp+30h],rbp00007ff6`c61c01ae 488d7320        lea     rsi,[rbx+20h] //这里对rbx做地址赋值00007ff6`c61c01b2 4c8d4240        lea     r8,[rdx+40h]00007ff6`c61c01b6 4533c9          xor     r9d,r9d00007ff6`c61c01b9 4889742428      mov     qword ptr [rsp+28h],rsi//这里对rsi对rsp地址赋值00007ff6`c61c01be 89442420        mov     dword ptr [rsp+20h],eax00007ff6`c61c01c2 e83910feff      call    yExam!sws_scale (00007ff6`c61a1200)

以上的分析可以从rsp栈中推倒出rsi和rbx,
这里写图片描述

  • frame
    但是根据上面的信息,无法得出frame的值,因为rdx 会在后续的调用中改变,而r8也会在sws_scale 中改变。
00007ff6`c61c0191 488b17          mov     rdx,qword ptr [rdi] //frame->frame00007ff6`c61c019d 8b426c          mov     eax,dword ptr [rdx+6Ch]//frame->frame->data,00007ff6`c61c01b2 4c8d4240        lea     r8,[rdx+40h]//frame->frame->height,

so我们网上查看调用者的信息, 找到r14寄存器
这里写图片描述

追寻r14寄存器发现ff_video_callback_frame中没有使用,而在sws_scale中做了push操作

这里写图片描述

最后可以根据r14 寄存器得出我们 的内容。
这里写图片描述

总结:windbg这个工具,不用就忘了,很久不用就生疏,所以对一些简单的流程做一下记录。

以上是在堆栈没有被溢出或者破坏的情况进行的,如果堆栈破坏很大的可能是数组越界。

原创粉丝点击