标签: callstack

调用堆栈中的"[Lightweight Function]"

我正在调试一个程序(VS2008),我正在逐步调试代码.我遇到了一个调用委托函数的行,我试图进入它.但是,不是像我预期的那样进入方法,而是绕过了这个方法,调试器改为踩到我认为是委托调用的函数.在调用堆栈中,我期望委托方法的行用文本显示为灰色[Lightweight Function].

"轻量级功能"部分是什么意思?有没有办法进入这个功能?

.net c# callstack visual-studio-2008

17
推荐指数
1
解决办法
3741
查看次数

为什么Minidumps不能提供良好的调用堆栈?

多年来我在很多游戏项目中都使用过minidumps,他们似乎有大约50%的机会拥有一个有效的调用堆栈.我该怎么做才能让他们有更好的调用堆栈?

我已经尝试将最新的dbghelp.dll放在exe目录中.这似乎有些帮助.

Visual Studio 2008或2010是否更好?(我还在VS 2005).

我使用的代码看起来像这个样本.

debugging minidump callstack dbghelp

17
推荐指数
2
解决办法
6386
查看次数

为什么它使用movl而不是push?

注意这段代码:

#include <stdio.h>
void a(int a, int b, int c)
{
    char buffer1[5];
    char buffer2[10];
}

int main()
{
    a(1,2,3); 
}
Run Code Online (Sandbox Code Playgroud)

之后 :

gcc -S a.c
Run Code Online (Sandbox Code Playgroud)

该命令在程序集中显示我们的源代码.

现在我们可以在main函数中看到,我们从不使用"push"命令将函数的参数压入堆栈.它用"movel"而不是那个

main:
 pushl %ebp
 movl %esp, %ebp
 andl $-16, %esp
 subl $16, %esp
 movl $3, 8(%esp)
 movl $2, 4(%esp)
 movl $1, (%esp)
 call a
 leave
Run Code Online (Sandbox Code Playgroud)

为什么会这样?他们之间有什么区别?

c assembly gcc callstack calling-convention

17
推荐指数
3
解决办法
4259
查看次数

当我写一个数组的末尾时,为什么我的程序没有崩溃?

为什么下面的代码没有任何崩溃@ runtime?

而且尺寸完全取决于机器/平台/编译器!! 我甚至可以在64位机器上放弃200.如何在OS中检测到主函数中的分段错误?

int main(int argc, char* argv[])
{
    int arr[3];
    arr[4] = 99;
}
Run Code Online (Sandbox Code Playgroud)

这个缓冲空间来自哪里?这是分配给进程的堆栈吗?

c stack callstack

16
推荐指数
2
解决办法
4389
查看次数

在断点处保持调用堆栈关闭

有没有办法让chrome dev工具中的调用堆栈面板崩溃?每当我遇到断点时它会扩展,迫使我向下滚动到范围.这使调试非常缓慢,有时令人愤怒.

谢谢/埃里克

javascript callstack google-chrome-devtools

16
推荐指数
1
解决办法
411
查看次数

C编译器可以重新排列堆栈变量吗?

我曾经在嵌入式系统的项目上工作过,我们重新安排了堆栈变量声明的顺序,以减少生成的可执行文件的大小.例如,如果我们有:

void func()
{
    char c;
    int i;
    short s;
    ...
}
Run Code Online (Sandbox Code Playgroud)

我们会将此重新排序为:

void func()
{
    int i;
    short s;
    char c;
    ...
}
Run Code Online (Sandbox Code Playgroud)

由于对齐问题,第一个导致使用12个字节的堆栈空间,第二个导致仅8个字节.

这是C编译器的标准行为,还是我们使用的编译器的缺点?

在我看来,编译器应该能够重新排序堆栈变量,以便在需要时支持更小的可执行文件大小.有人向我建议,C标准的某些方面可以防止这种情况,但我无法以任何方式找到信誉良好的来源.

作为一个额外的问题,这也适用于C++编译器吗?

编辑

如果答案是肯定的,那么C/C++编译器可以重新排列堆栈变量,你能给出一个肯定会这样做的编译器的例子吗?我想看看编译器文档或类似的东西支持这一点.

再次编辑

谢谢大家的帮助.对于文档,我能够找到的最好的东西是GCC(pdf)中的最佳堆栈槽分配,由Naveen Sharma和Sanjiv Kumar Gupta撰写,于2003年在海湾合作委员会峰会会议上提交.

这里讨论的项目是使用ADS编译器进行ARM开发.在该编译器的文档中提到,像我所示的排序声明可以提高性能以及堆栈大小,因为ARM-Thumb架构如何计算本地堆栈帧中的地址.该编译器没有自动重新排列本地人以利用这一点.这里链接的论文说,截至2003年,GCC也没有重新安排堆栈帧以改善ARM-Thumb处理器的参考局部性,但它暗示你可以.

我找不到任何明确表示这在GCC中实施过的东西,但我认为这篇论文可以证明你是正确的.再次感谢.

c c++ compiler-construction callstack alignment

15
推荐指数
5
解决办法
4641
查看次数

如何在没有有用的调用堆栈的情况下调试难以重现的崩溃?

我在软件中遇到了一个奇怪的崩溃,我在调试它时遇到了很多麻烦,因此我正在寻求如何解决它的建议.

崩溃是读取NULL指针的访问冲突:

$ 00CF0041的第一次机会异常.异常类$ C0000005,消息'访问冲突位于0x00cf0041:读取地址0x00000000'.

它只发生'有时' - 我还没有设法找出任何押韵或理由,但是,当时 - 并且只在主线程中.当它发生时,调用堆栈包含一个不正确的条目:

用一行调用堆栈,Classes :: TList :: Get,地址0x00cf0041

对于主线程,它应该显示一个充满其他项目的大堆栈.

此时,所有其他线程都处于非活动状态(主要是坐在WaitForSingleObject或类似的功能.)我只看到这个崩溃发生在主线程中.它始终具有一个条目的相同调用堆栈,在同一地址的相同方法中.此方法可能相关也可能不相关 - 我们在应用程序中使用VCL.不过,我的赌注是,某些东西(可能是很久以前)正在破坏堆栈,而崩溃的地址实际上是随机的.请注意,它在几个版本中的地址相同 - 但它可能不是真正随机的.

这是我尝试过的:

  • 试图在某一点可靠地再现它.我没有发现任何东西每次都会重现它,以及偶尔做或不做的一些事情,没有明显的理由.这些并不是"狭隘"的足以将其缩小到特定代码段的行为.它可能与时间有关,但在IDE中断的时候,其他线程通常什么都不做.我不能排除线程问题,但认为这不太可能.
  • 使用额外的调试语句构建(额外的调试信息,额外的断言等).这样做之后,崩溃永远不会发生.
  • 在启用Codeguard的情况下构建.执行此操作后,崩溃永远不会发生,Codeguard没有显示错误.

我的问题:

1.如何找到导致崩溃的代码?我怎么做相当于走回堆栈?

2.对于如何追踪此次崩溃的原因,您有什么一般性的建议?

我正在使用Embarcadero RAD Studio 2010(该项目主要包含C++ Builder代码和少量Delphi.)

编辑:我想我应该添加实际导致这个的东西.有一个线程调用ReadDirectoryChangesW然后,使用GetOverlappedResult,等待事件继续并对更改执行某些操作.事件也发出信号,以便在设置状态标志后终止线程.问题是当线程退出时它从未调用过CancelIO.因此,Windows仍在跟踪更改,并且可能仍然在目录更改时写入缓冲区,即使缓冲区,重叠的结构和事件不再存在(也没有创建它们的线程上下文.)CancelIO调用时,没有更多的崩溃.

delphi crash callstack c++builder

15
推荐指数
1
解决办法
5442
查看次数

调用堆栈没有说"你来自哪里",而是"你下一步去哪里"?

在上一个问题(获取对象调用层次结构)中,我得到了这个有趣的答案:

调用堆栈不是告诉你你来自哪里.它是告诉你下一步的去向.

据我所知,当到达函数调用时,程序通常会执行以下操作:

  1. 调用代码时:

    • 存储返回地址(在调用堆栈上)
    • 保存寄存器的状态(在调用堆栈上)
    • 写入将传递给函数的参数(在调用堆栈或寄存器中)
    • 跳转到目标函数

  2. 被叫目标代码中:

    • 检索存储的变量(如果需要)

  3. 返回过程:撤消我们调用函数时所做的操作,即展开/弹出调用堆栈:

    • 从调用堆栈中删除局部变量
    • 从调用堆栈中删除函数变量
    • 恢复寄存器状态(我们之前存储的状态)
    • 跳转到返回地址(我们之前存储的地址)

题:

如何将其视为"告诉您下一步的去向"而不是"告诉您从何而来"

在C#的JIT或C#的运行时环境中是否存在使得调用堆栈以不同方式工作的东西?

感谢有关调用堆栈描述的文档的任何指示 - 有大量关于传统调用堆栈如何工作的文档.

.net c# callstack

15
推荐指数
2
解决办法
2045
查看次数

在amd64上拆分堆栈是不必要的

似乎有一种观点认为在64位体系结构上使用"拆分堆栈"运行时模型是不必要的.我说似乎是,因为我还没有看到有人说过,只能围着它跳舞:

典型的多线程程序的内存使用量可能会显着降低,因为每个线程不需要最坏情况的堆栈大小.可以在32位地址空间中运行数百万个线程(完整的NPTL线程或协同例程).- 伊恩兰斯泰勒

...暗示64位地址空间已经可以处理它.

和...

...分离堆栈的持续开销和狭窄的用例(在32位体系结构上产生大量的I/O绑定任务)是不可接受的... - bstrie

两个问题:这是他们说的吗?其次,如果是这样,为什么它们在64位架构上不必要?

64-bit multithreading callstack go rust

15
推荐指数
2
解决办法
1219
查看次数

c#setter中的堆栈溢出异常

这很容易解释:这很有效

using System;
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>;

namespace ConsoleApplication2
{
    class test
    {
        public ConstraintSet a { get; set; }
        public test()
        {
            a = new ConstraintSet();
        }
        static void Main(string[] args)
        {
            test abc = new test();
            Console.WriteLine("done");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这不

using System;
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>;

namespace ConsoleApplication2
{
    class test
    {
        public ConstraintSet a { get { return a; } set { a = value; } }
        public test()
        {
            a = new ConstraintSet(); …
Run Code Online (Sandbox Code Playgroud)

c# stack-overflow setter callstack

14
推荐指数
3
解决办法
8133
查看次数