代码之家  ›  专栏  ›  技术社区  ›  Dominique

调试器能否生成附加进程的所有已执行源代码行的列表?

  •  0
  • Dominique  · 技术社区  · 7 年前

    我在一家公司工作,它没有在源代码中添加日志项的习惯。

    因此,如果出现问题,解释可能发生的情况的日志数量太少,无法进行任何真正的分析。

    因此,我正在寻找一种可以实现以下功能的工具:

    • 附加到正在运行的进程并链接到符号文件。
    • 遵循执行的所有源代码行。
    • 按下某个键(如“Ctrl+C”)后,生成如下报告:

    []

    file1.c:010:  function1(1, 2, 5)
    file1.c:011:    sum(1,2)
    file1.c:020:      return 3;
    file1.c:012:    sum(3,5);
    file1.c:020:      return 8;
    file1.c:012:    return 8;
    

    有人知道这是否可以通过使用 windbg , cdb 、Visual Studio或任何其他方式?

    1 回复  |  直到 7 年前
        1
  •  2
  •   blabb    7 年前

    你有exe的源代码和符号吗 如果是,windbg可以单步执行并打印源行

    下面是一个简单的recv示例演示

    启动一个可执行文件,其带有src info的pdb可用

    :\>cdb recv
    
    Microsoft (R) Windows Debugger Version 10.0.16299.15 X86
    

    windbg在系统断点上中断

    ntdll!LdrpDoDebuggerBreak+0x2c:
    771a05a6 cc              int     3
    

    启用线路信息加载 启用在源模式下单步执行 启用src行的打印

    0:000> .lines
    Line number information will be loaded
    0:000> l+t
    Source options are 1:
         1/t - Step/trace by source line
    0:000> l+s
    Source options are 5:
         1/t - Step/trace by source line
         4/s - List source code at prompt
    

    不允许除src之外的所有其他输出

    0:000> .prompt_allow -reg -dis -sym -ea
    Allow the following information to be displayed at the prompt:
    (Other settings can affect whether the information is actually displayed)
       src - Source info for current instruction
    Do not allow the following information to be displayed at the prompt:
       sym - Symbol for current instruction
       dis - Disassembly of current instruction
        ea - Effective address for current instruction
       reg - Register state
    

    转到主步骤和步骤10次 您将看到每个步骤都显示了src

    阅读并使用windbg中的控制目标帮助了解各种 执行方法,如step until return、step until branch等

    0:000> g recv!main
    ModLoad: 69f50000 69f53000   C:\Windows\system32\api-ms-win-core-synch-l1-2-0.DLL
    >   13: int __cdecl main() {
    0:000> p 10
    >   24:     iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    >   25:     if (iResult != NO_ERROR) {
    >   30:     ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    >   31:     if (ConnectSocket == INVALID_SOCKET) {
    >   38:     clientService.sin_family = AF_INET;
    >   39:     clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    >   40:     clientService.sin_port = htons( 27015 );
    >   42:     iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    >   43:     if ( iResult == SOCKET_ERROR) {
    >   44:         closesocket (ConnectSocket);
    >   45:         printf("Unable to connect to server: %ld\n", WSAGetLastError());
    
    Unable to connect to server: 0
    >   66:         WSACleanup();
    >   67:         return 1;
    >   88: }
    *** The C++ standard library and CRT step filter can be enabled to skip this fun
    ction. Run .settings set Sources.SkipCrtCode = true">.settings set Sources.SkipC
    rtCode = true to enable it. ***
    
    推荐文章