gpt4 book ai didi

gcc - gprof 不为需要合理时间执行的程序产生任何输出

转载 作者:行者123 更新时间:2023-12-04 11:44:02 29 4
gpt4 key购买 nike

我知道以前有人问过类似的问题,但是:

  • 关于 gprof produces empty output 我在 Windows 10 上使用来自 MSYS2 的 GCC 10.2.0,即它是 MingW64 发行版。我还将 -no-pie 添加到链接器参数中,但仍然没有结果。 GNU Prof 的版本是 2.36.1
  • 关于 gprof gives no output 我正在一个明确需要时间执行的程序上执行它。

  • 该程序是来自 this tutorial 的代码,复制如下:
    //test_gprof.c
    #include<stdio.h>

    void new_func1(void)
    {
    printf("\n Inside new_func1()\n");
    int i = 0;

    for(;i<0xffffffee;i++);

    return;
    }

    void func1(void)
    {
    printf("\n Inside func1 \n");
    int i = 0;

    for(;i<0xffffffff;i++);
    new_func1();

    return;
    }

    static void func2(void)
    {
    printf("\n Inside func2 \n");
    int i = 0;

    for(;i<0xffffffaa;i++);
    return;
    }

    int main(void)
    {
    printf("\n Inside main()\n");
    int i = 0;

    for(;i<0xffffff;i++);
    func1();
    func2();

    return 0;
    }
    我正在使用 Code::Blocks 进行构建。我已经尝试过 MSYS2 的 32 位和 64 位版本的 MingW。我已将所有内容升级到可用软件包的最新版本。
    Code::Blocks 构建日志的输出:
    g++.exe -pg -c C:\Users\david\Documents\GameDev\CPPTESTS\main.cpp -o obj\Debug\CPPTESTS\main.o
    g++.exe -o CPPTESTS-d.exe obj\Debug\CPPTESTS\main.o -pg -lgmon -no-pie
    程序编译并成功执行。执行后,会生成一个gmon.out 文件。执行 gprof 来解释这个文件:
     gprof CPPTests-d.exe gmon.out > gprofoutput.txt
    gprofoutput.txt 中产生以下内容:
    Flat profile:

    Each sample counts as 0.01 seconds.
    % cumulative self self total
    time seconds seconds calls Ts/call Ts/call name

    % the percentage of the total running time of the
    time program used by this function.

    cumulative a running sum of the number of seconds accounted
    seconds for by this function and those listed above it.

    self the number of seconds accounted for by this
    seconds function alone. This is the major sort for this
    listing.

    calls the number of times this function was invoked, if
    this function is profiled, else blank.

    self the average number of milliseconds spent in this
    ms/call function per call, if this function is profiled,
    else blank.

    total the average number of milliseconds spent in this
    ms/call function and its descendents per call, if this
    function is profiled, else blank.

    name the name of the function. This is the minor sort
    for this listing. The index shows the location of
    the function in the gprof listing. If the index is
    in parenthesis it shows where it would appear in
    the gprof listing if it were to be printed.

    Copyright (C) 2012-2021 Free Software Foundation, Inc.

    Copying and distribution of this file, with or without modification,
    are permitted in any medium without royalty provided the copyright
    notice and this notice are preserved.

    Call graph (explanation follows)


    granularity: each sample hit covers 4 byte(s) no time propagated

    index % time self children called name

    This table describes the call tree of the program, and was sorted by
    the total amount of time spent in each function and its children.

    Each entry in this table consists of several lines. The line with the
    index number at the left hand margin lists the current function.
    The lines above it list the functions that called this function,
    and the lines below it list the functions this one called.
    This line lists:
    index A unique number given to each element of the table.
    Index numbers are sorted numerically.
    The index number is printed next to every function name so
    it is easier to look up where the function is in the table.

    % time This is the percentage of the `total' time that was spent
    in this function and its children. Note that due to
    different viewpoints, functions excluded by options, etc,
    these numbers will NOT add up to 100%.

    self This is the total amount of time spent in this function.

    children This is the total amount of time propagated into this
    function by its children.

    called This is the number of times the function was called.
    If the function called itself recursively, the number
    only includes non-recursive calls, and is followed by
    a `+' and the number of recursive calls.

    name The name of the current function. The index number is
    printed after it. If the function is a member of a
    cycle, the cycle number is printed between the
    function's name and the index number.


    For the function's parents, the fields have the following meanings:

    self This is the amount of time that was propagated directly
    from the function into this parent.

    children This is the amount of time that was propagated from
    the function's children into this parent.

    called This is the number of times this parent called the
    function `/' the total number of times the function
    was called. Recursive calls to the function are not
    included in the number after the `/'.

    name This is the name of the parent. The parent's index
    number is printed after it. If the parent is a
    member of a cycle, the cycle number is printed between
    the name and the index number.

    If the parents of the function cannot be determined, the word
    `<spontaneous>' is printed in the `name' field, and all the other
    fields are blank.

    For the function's children, the fields have the following meanings:

    self This is the amount of time that was propagated directly
    from the child into the function.

    children This is the amount of time that was propagated from the
    child's children to the function.

    called This is the number of times the function called
    this child `/' the total number of times the child
    was called. Recursive calls by the child are not
    listed in the number after the `/'.

    name This is the name of the child. The child's index
    number is printed after it. If the child is a
    member of a cycle, the cycle number is printed
    between the name and the index number.

    If there are any cycles (circles) in the call graph, there is an
    entry for the cycle-as-a-whole. This entry shows who called the
    cycle (as parents) and the members of the cycle (as children.)
    The `+' recursive calls entry shows the number of function calls that
    were internal to the cycle, and the calls entry for each member shows,
    for that member, how many times it was called from other members of
    the cycle.

    Copyright (C) 2012-2021 Free Software Foundation, Inc.

    Copying and distribution of this file, with or without modification,
    are permitted in any medium without royalty provided the copyright
    notice and this notice are preserved.

    Index by function name
    你可以看到它完全是空的。此外,如果我在十六进制编辑器中打开 gmon.out,里面大部分是空白的,这是第一位:
    F0 14 C5 00 18 8A C5 00 B4 3A 00 00 79 18 05 00 64 00 00 00 96 1A C5 00 A7 16 C5 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 FE 00 5D 00 E2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 00 C6 01 A5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06 00 E5 00 77 00 F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    然后最后是以下内容:
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E4 15 C5 00 6C 89 C5 00 01 00 00 00 14 16 C5 00 6C 89 C5 00 01 00 00 00 2C 16 C5 00 DB 15 C5 00 01 00 00 00 48 16 C5 00 6C 89 C5 00 01 00 00 00 84 16 C5 00 6C 89 C5 00 01 00 00 00 A0 16 C5 00 0A 16 C5 00 01 00 00 00 A4 16 C5 00 3C 16 C5 00 01 00 00 00
    其余的是几千字节的 00
    我已经尝试了所有我可以在谷歌找到的关于让它工作的方法。最初我在一个项目的实际代码上执行它时遇到了麻烦,但我不得不使用上面的代码,因为似乎我做错了一些我无法弄清楚的事情。
    任何帮助,将不胜感激。
    编辑
    我设法在 gmon.out 中生成了用 gprof 正确解析的结果,并为我的测试程序中的所有函数提供了计时。没有做任何改变,甚至没有关闭 MSYS2 终端(我放弃了 Code::Blocks 以确保它不是问题),然后我用相同的命令重新编译程序,再次执行它,并返回一个空结果。
    我不清楚它是在编译过程中发生了什么(很难相信,它是使用终端历史记录中的最后一个命令编译的),还是在我执行它时在我的机器上发生了什么。或者如果 gprof 翻译 gmon.out 文件有问题。
    编辑 2
    我在从未用于开发的另一台机器(它是类似的 Windows 10 Surface Pro)上执行了该程序。当通过 gprof 解析时,它产生的 gmon.out 似乎也没有结果。
    编辑 3
    我已经厌倦了 gcc 和 g++ 的相同结果。我尝试过单独的编译和链接步骤,或者同时进行。我也试过链接到 -lgmon 或不链接。解析 gprof 时,所有结果都相同。
    自从它工作的一个随机时间以来,我一直无法再次获得结果。
    编辑 4
    我用 -g-pg 编译了程序,然后通过 VTune 运行它。我可以在热点分析中看到正在调用与分析器相关的函数调用。
    这是整个被调用者堆栈。您可以看到正在调用与配置文件相关的函数调用 profthr_funcget_thrpc
    Callees CPU Time: Total CPU Time: Self
    BaseThreadInitThunk 100.0% 0s
    _tmainCRTStartup 99.1% 0s
    main 99.1% 0.016s
    func1 65.8% 20.521s
    new_func1 32.8% 20.456s
    func2 33.2% 20.695s
    profthr_func 0.6% 0.009s
    WaitForSingleObject 0.4% 0.231s
    get_thrpc 0.2% 0s
    SwitchToThread 0.2% 0.116s
    TlsGetValue 0.0% 0.002s
    GetLastError 0.0% 0.001s
    SwitchToThread 0.0% 0.001s
    GetLastError 0.0% 0.001s
    [Outside any known module] 0.0% 0.001s
    func@0x4b308730 0.0% 0.000s
    TlsGetValue 0.0% 0.000s
    get_thrpc 0.4% 0s
    GetThreadContext 0.3% 0.214s
    GetLastError 0.0% 0.006s
    TlsGetValue 0.0% 0.000s
    [Outside any known module] 0.0% 0.002s
    SuspendThread 0.0% 0.001s
    [Unknown stack frame(s)] 0.0% 0s
    profthr_func 0.0% 0s
    WaitForSingleObject 0.0% 0.000s
    然后是所有功能及其来源等:
    Function                    CPU Time: Total CPU Time: Self  Module          Function (Full)             Source File Start Address
    BaseThreadInitThunk 100.0% 0s kernel32.dll BaseThreadInitThunk [Unknown] 0x6b81fa10
    func@0x4b2e7a03 100.0% 0s ntdll.dll func@0x4b2e7a03 [Unknown] 0x4b2e7a03
    func@0x4b2e7a1f 100.0% 0s ntdll.dll func@0x4b2e7a1f [Unknown] 0x4b2e7a1f
    _tmainCRTStartup 99.1% 0s CPPTESTS-d.exe _tmainCRTStartup crtexe.c 0x401170
    main 99.1% 0.016s CPPTESTS-d.exe main main.cpp 0x40165c
    func1 65.8% 20.521s CPPTESTS-d.exe func1(void) main.cpp 0x4015fd
    func2 33.2% 20.695s CPPTESTS-d.exe func2 main.cpp 0x40162f
    new_func1 32.8% 20.456s CPPTESTS-d.exe new_func1(void) main.cpp 0x4015d0
    profthr_func 0.6% 0.009s CPPTESTS-d.exe profthr_func profil.c 0x408620
    get_thrpc 0.5% 0s CPPTESTS-d.exe get_thrpc profil.c 0x4085c0
    WaitForSingleObject 0.4% 0.231s KernelBase.dll WaitForSingleObject [Unknown] 0x10110440
    GetThreadContext 0.3% 0.214s KernelBase.dll GetThreadContext [Unknown] 0x101b61a0
    SwitchToThread 0.2% 0.116s KernelBase.dll SwitchToThread [Unknown] 0x100f5b40
    GetLastError 0.0% 0.007s kernel32.dll GetLastError [Unknown] 0x6b81e010
    [Outside any known module] 0.0% 0.002s [Unknown] [Outside any known module] [Unknown] 0
    TlsGetValue 0.0% 0.002s KernelBase.dll TlsGetValue [Unknown] 0x101193a0
    SuspendThread 0.0% 0.001s kernel32.dll SuspendThread [Unknown] 0x6b834e90
    SwitchToThread 0.0% 0.001s kernel32.dll SwitchToThread [Unknown] 0x6b817cc0
    GetLastError 0.0% 0.001s KernelBase.dll GetLastError [Unknown] 0x10110580
    TlsGetValue 0.0% 0.000s kernel32.dll TlsGetValue [Unknown] 0x6b81df20
    func@0x4b308730 0.0% 0.000s ntdll.dll func@0x4b308730 [Unknown] 0x4b308730
    [Unknown stack frame(s)] 0.0% 0s [Unknown] [Unknown stack frame(s)] [Unknown] 0
    我不确定这些信息是否有助于解决我的问题。 gmon.out 文件再次通过 gprof 解析时,没有任何信息。
    我读过 this answer to a question about how gprof works ,所以我希望对 mainfunc1func2new_func1 的调用会带有某种乐器调用?
    我运行了 VTune 并检查了 Threading 选项,并注意到 gprof 似乎是通过一个新线程来完成它的,这与我上面的理解不同。但是,它并没有解释为什么我曾经得到一些输出并且无法重新创建它。
    但是,在 Vtune 中,我没有看到对 mcount 的调用,我认为这是 gprof 的工作方式。它确实向我展示了来自 -pg 标志的分析 内容 的点点滴滴(如您在上面的调用堆栈和函数列表中所见)。
    编辑 5
    我已经上传了我的 compiled program 并且它是 gmon.out 以防它帮助任何人帮助回答问题。
    编辑 6
    我重新安装了 MSYS2,希望能解决问题。它没有。
    编辑 7
    我试过与 -static -static-libgcc -static-libstdc++ 链接。它没有效果。
    编辑 8
    我已经用 -d 标志执行了 gprof。 Debug output can be found here 。但这对我来说大多只是胡言乱语。
    编辑 9
    我已经在 MSYS2 之外直接安装了 Mingw-Builds 并在 i686 和 86_64 版本中测试了 8.1.0 版、Dwarf 和 SJLJ。用这个版本的 G++ 编译和链接后,生成了一个 gmon.out 文件,但是 gprof 给出了以下错误(或者是数字的变体):
    BFD: Dwarf Error: Could not find abbrev number 108.
    但是生成的输出有效。我还检查了 8.1.0 编译的程序 gmon.out 可以被较新的 MSYS2 gprof 解析而没有问题。因此,问题似乎出在较新版本的 Mingw64 上。
    Gprof 报告版本 2.30,G++ 报告版本 8.1.0。
    编辑 10
    我已经尝试在干净的 Windows 7 Virtual Box 机器上编译和运行 gprof 并获得相同的结果。所以我不是我的操作系统(Windows 10)或我的特定计算机。
    看起来这个问题在这里没有得到回答。如果我弄清楚了,我会回答这个问题。在那之前,我已经在 MSYS2 trackerMingw64 tracker 上创建了问题。
    编辑 11
    我现在一直在研究以下代码:
    #include <iostream>

    bool is_prime(const int& number)
    {
    if(number == 0 || number == 1)
    return false;
    else
    {
    for(int i = 2; i <= number / 2; ++i)
    {
    if(number % i == 0)
    {
    return false;
    }
    }
    }

    return true;
    }

    int main()
    {
    int low = 0;
    int high = 300000;

    while(low < high)
    {
    if(is_prime(low))
    std::cout << low << ", ";

    ++low;
    }

    std::cout << std::endl;
    return 0;
    }
    使用与之前的 g++ -g -pg -O0 main.cpp -o CPPTESTS-d.exe 相同的编译器标志 objdump -d CPPTESTS-d.exe 为我提供了来自 mainis_prime 部分的以下内容:
    004015d0 <__Z8is_primeRKi>:
    4015d0: 55 push %ebp
    4015d1: 89 e5 mov %esp,%ebp
    4015d3: 83 ec 10 sub $0x10,%esp
    4015d6: e8 a5 15 00 00 call 402b80 <_mcount>
    4015db: 8b 45 08 mov 0x8(%ebp),%eax
    4015de: 8b 00 mov (%eax),%eax
    4015e0: 85 c0 test %eax,%eax
    4015e2: 74 0a je 4015ee <__Z8is_primeRKi+0x1e>
    4015e4: 8b 45 08 mov 0x8(%ebp),%eax
    4015e7: 8b 00 mov (%eax),%eax
    4015e9: 83 f8 01 cmp $0x1,%eax
    4015ec: 75 07 jne 4015f5 <__Z8is_primeRKi+0x25>
    4015ee: b8 00 00 00 00 mov $0x0,%eax
    4015f3: eb 3b jmp 401630 <__Z8is_primeRKi+0x60>
    4015f5: c7 45 fc 02 00 00 00 movl $0x2,-0x4(%ebp)
    4015fc: 8b 45 08 mov 0x8(%ebp),%eax
    4015ff: 8b 00 mov (%eax),%eax
    401601: 89 c2 mov %eax,%edx
    401603: c1 ea 1f shr $0x1f,%edx
    401606: 01 d0 add %edx,%eax
    401608: d1 f8 sar %eax
    40160a: 39 45 fc cmp %eax,-0x4(%ebp)
    40160d: 7f 1c jg 40162b <__Z8is_primeRKi+0x5b>
    40160f: 8b 45 08 mov 0x8(%ebp),%eax
    401612: 8b 00 mov (%eax),%eax
    401614: 99 cltd
    401615: f7 7d fc idivl -0x4(%ebp)
    401618: 89 d0 mov %edx,%eax
    40161a: 85 c0 test %eax,%eax
    40161c: 75 07 jne 401625 <__Z8is_primeRKi+0x55>
    40161e: b8 00 00 00 00 mov $0x0,%eax
    401623: eb 0b jmp 401630 <__Z8is_primeRKi+0x60>
    401625: 83 45 fc 01 addl $0x1,-0x4(%ebp)
    401629: eb d1 jmp 4015fc <__Z8is_primeRKi+0x2c>
    40162b: b8 01 00 00 00 mov $0x1,%eax
    401630: c9 leave
    401631: c3 ret

    00401632 <_main>:
    401632: 8d 4c 24 04 lea 0x4(%esp),%ecx
    401636: 83 e4 f0 and $0xfffffff0,%esp
    401639: ff 71 fc push -0x4(%ecx)
    40163c: 55 push %ebp
    40163d: 89 e5 mov %esp,%ebp
    40163f: 51 push %ecx
    401640: 83 ec 24 sub $0x24,%esp
    401643: e8 38 15 00 00 call 402b80 <_mcount>
    401648: e8 73 1a 00 00 call 4030c0 <__monstartup>
    40164d: e8 be 01 00 00 call 401810 <___main>
    401652: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
    401659: c7 45 f4 e0 93 04 00 movl $0x493e0,-0xc(%ebp)
    401660: 8b 45 f0 mov -0x10(%ebp),%eax
    401663: 39 45 f4 cmp %eax,-0xc(%ebp)
    401666: 7e 3d jle 4016a5 <__fu0___ZSt4cout+0x27>
    401668: 8d 45 f0 lea -0x10(%ebp),%eax
    40166b: 89 04 24 mov %eax,(%esp)
    40166e: e8 5d ff ff ff call 4015d0 <__Z8is_primeRKi>
    401673: 84 c0 test %al,%al
    401675: 74 23 je 40169a <__fu0___ZSt4cout+0x1c>
    401677: 8b 45 f0 mov -0x10(%ebp),%eax
    40167a: 89 04 24 mov %eax,(%esp)
    40167d: b9 .byte 0xb9
    我可以看到 mcount 在两者的开头都被调用。因此,编译后的代码似乎已正确检测,但 gprof 中仍然没有输出。

    最佳答案

    这似乎是新版 MinGW 中的一个错误。我之前也遇到过同样的问题。我的 MinGW 是从 winlibs 下载的。当我尝试使用最新版本9.0时,gprof的输出结果确实为空。我尝试了 MinGW 9.0 版和 GCC 11、10 和 9 版,结果都是空的。最后找到了mingw7.0.0-gcc10.2,尝试用这个版本编译,运行然后使用gprof,输出结果不为空,但与Linux平台使用gprof相比,结果有点奇怪

    关于gcc - gprof 不为需要合理时间执行的程序产生任何输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67240792/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com