gpt4 book ai didi

Delphi SampleProfiler : How is this code calling into ntdll. dll?

转载 作者:行者123 更新时间:2023-12-03 14:48:57 27 4
gpt4 key购买 nike

我使用 Delphi Sampling Profiler 分析了我的应用程序的一部分. Like most people ,我看到大部分时间都花在了里面 ntdll.dll .

Note: i turned on the options to ignore Application.Idle time, and calls from System.pas. So it isn't inside ntdll because the application is idle:

alt text



经过多次运行,多次,大部分时间似乎都花在了 ntdll.dll里面,但奇怪的是来电者是谁:

enter image description here

调用者来自虚拟树 View :
PrepareCell(PaintInfo, Window.Left, NodeBitmap.Width);    

Note: The application is not inside ntdll.dll because the application is idle, because the caller isn't Application.Idle.



让我困惑的是,是这条线 本身 (即不是 里面的东西 PrepareCell)是进入 ntdll 的调用者.更令人困惑的是:
  • 不仅是不是 东西 PrepareCell()
  • 它甚至不是 PrepareCell 的设置(例如,弹出堆栈变量,设置隐式异常帧等)是调用者。这些东西会在分析器中显示为 begin 上的热点。在 PrepareCell 内部。

  • VirtualTrees.pas:
    procedure TBaseVirtualTree.PrepareCell(var PaintInfo: TVTPaintInfo; WindowOrgX, MaxWidth: Integer);
    begin
    ...
    end;

    所以我想弄清楚这条线如何:
    PrepareCell(PaintInfo, Window.Left, NodeBitmap.Width);    

    正在拨打 ntdll.dll .

    唯一的其他方式是三个参数:
  • PaintInfo
  • Window.Left
  • NodeBitmap.Width

  • 也许其中之一是函数或属性 getter,它会调用 ntdll .所以我在行上放了一个断点,在运行时查看CPU窗口:

    alt text

    那里 那里的一行可能是罪魁祸首:
    call dword ptr [edx+$2c]

    但是当我跟随那个跳跃时,它并没有以 ntdll.dll 结束。 ,但是 TBitmap.GetWidth :

    alt text

    如您所见,它不会在任何地方调用;肯定不会进入 ntdll.dll .

    那么线路如何:
    PrepareCell(PaintInfo, Window.Left, NodeBitmap.Width);    

    呼入 ntdll.dll ?

    注:我很清楚它并没有真正调用 ntdll.dll。因此,任何有效的答案都必须包含“Sampling Profiler 具有误导性;该行没有调用 ntdll.dll”。答案也必须要么说大部分时间是 不是 在 ntdll.dll 中花费,或者突出显示的行不是调用者。最后,任何答案都必须解释为什么 Sampling Profiler 是错误的,以及如何修复它。

    更新 2

    ntdll.dll 是什么? Ntdll 是 Windows NT 的 native API 集。 Win32 API 是 ntdll.dll 的包装器那个 看起来像 Windows 1/2/3/9x 中存在的 Windows API。为了真正进入 ntdll,您必须调用一个直接或间接使用 ntdll 的函数。

    例如,当我的 Delphi 应用程序空闲时,它通过调用 user32.dll 函数等待消息:
    WaitMessage;

    当你真正看它的时候是:
    USER32.WaitMessage
    mov eax,$00001226
    mov edx,$7ffe0300
    call dword ptr [edx]
    ret

    调用在 $7ffe0300 指定的函数是 Windows 转换到 Ring0 的方式,调用 EAX 中指定的 FunctionID。在这种情况下,被调用的系统函数是 0x1226。在我的操作系统Windows Vista上,0x1226对应系统函数 NtUserWaitMessage .

    这是您进入 ntdll.dll 的方法:您调用它。

    我是 拼命当我提出原始问题时,试图避免挥手不回答。通过非常具体,仔细指出我所看到的现实,我试图防止人们忽视事实,并试图使用挥手的论点。

    更新三

    我转换了两个参数:
    PrepareCell(PaintInfo, Window.Left, NodeBitmap.Width);

    进入堆栈变量:
    _profiler_WindowLeft := Window.Left;
    _profiler_NodeBitmapWidth := NodeBitmap.Width;
    PrepareCell(PaintInfo, _profiler_WindowLeft, _profiler_NodeBitmapWidth);

    确认瓶颈不是调用
  • Windows.Left , 或
  • Nodebitmap.Width

  • Profiler 仍然表明该行
    PrepareCell(PaintInfo, _profiler_WindowLeft, _profiler_NodeBitmapWidth);

    本身就是瓶颈;没什么 准备细胞。此 必须意味着它在准备单元的调用设置中,或者在 PrepareCell 的开始:
    VirtualTrees.pas.15746: PrepareCell(PaintInfo, _profiler_WindowLeft, _profiler_NodeBitmapWidth);
    mov eax,[ebp-$54]
    push eax
    mov edx,esi
    mov ecx,[ebp-$50]
    mov eax,[ebp-$04]
    call TBasevirtualTree.PrepareCell

    其中没有任何内容调用 ntdll。现在 PrepareCell 本身的前导码:
    VirtualTrees.pas.15746: begin
    push ebp
    mov ebp,esp
    add esp,-$44
    push ebx
    push esi
    push edi
    mov [ebp-$14],ecx
    mov [ebp-$18],edx
    mov [ebp-$1c],eax
    lea esi,[ebp-$1c]
    mov edi,[ebp-$18]

    里面没有任何东西可以调用 ntdll.dll .

    问题仍然存在:
  • 为什么将一个变量插入堆栈,将另外两个插入寄存器会成为瓶颈?
  • 为什么 PrepareCell 内部的任何东西都不是瓶颈?
  • 最佳答案

    好吧,这个问题实际上是我制作自己的采样分析器的主要原因:
    http://code.google.com/p/asmprofiler/wiki/AsmProfilerSamplingMode

    也许不完美,但你可以试一试。让我知道你对此的看法。

    顺便说一句,我认为这与几乎所有调用都以调用内核(内存请求、绘制事件等)结束的事实有关。只有计算不需要调用内核。
    大多数调用以等待内核结果结束:

    ntdll.dll!KiFastSystemCallRet

    您可以在带有线程堆栈 View 的 Process Explorer 或 Delphi 中看到这一点,或者在我的 AsmProfiler 的“实时 View ”中使用 StackWalk64 API:
    http://code.google.com/p/asmprofiler/wiki/ProcessStackViewer

    关于Delphi SampleProfiler : How is this code calling into ntdll. dll?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2623123/

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