问题标签 [stack-frame]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
3914 浏览

c# - 有没有一种简单的方法可以在 C#(或 CIL)中获取当前堆栈帧中的所有局部变量

在我之前的问题之后,我想转储堆栈中的所有变量(从当前帧和所有前一帧),可以在这里看到:有没有办法在 C# 中在运行时检查堆栈变量?

有人建议我手动拦截调用或使用 PostSharp 之类的 AOP 框架来简化此类任务。我查看了 PostSharp,拦截参数不包括当前堆栈帧中的变量。我想知道是否有一种简单的方法可以自动获取当前堆栈帧中的所有局部变量。我想我可以执行代码分析并生成将所有这些值复制到集合中的代码,但也许有一个内置机制可以做到这一点。

在此先感谢您的任何建议。

编辑:我应该更详细地说明我为什么要这样做。我希望能够在方法中间暂停执行。如果我有堆栈的内容,我可以稍后恢复执行,甚至可以将其序列化并在另一台机器上继续执行(假设它是相对简单的代码,因此没有线程或 I/O)。可以运行一个代码分析工具,它可以让我自动生成额外的代码来保存这个状态。我想我可能必须分析 CIL 才能做到这一点。

0 投票
1 回答
3485 浏览

c# - 异常调用堆栈被截断,没有任何重新抛出

我有一个不寻常的情况,我有一个非常简单的异常被抛出并以相同的方法捕获。 它不会被重新抛出(天真的程序员通常会遇到的问题)。然而它的 StackFrame 只包含一个当前方法。这是它的样子:

实际上,在 VS2010 调试器的调用堆栈中可能有 30 种方法导致此问题,涉及六个不同的程序集。似乎不可能对所有这些进行优化。此外,此代码是在调试模式下构建的,没有针对 .NET 4 进行优化。我什至有(基于http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx).ini文件(包括一个在同一文件夹中命名为 [app].vshost.ini),其中包含:

此外,方法调用不在方法的末尾,因此尾递归优化似乎更不可能。

至于如何调用它:调用堆栈上没有使用反射,没有任何类型的 Invoke() 或 BeginInvoke()。这只是单击按钮的一长串调用。点击处理程序在调用堆栈中大约有 10 个调用。下面是通常的 WndProc、NativeWindow.Callback、本机/托管转换和消息循环。这最终在从 C# EXE 程序集运行的 ShowDialog() 调用中。

现在,我发现我可以在我的 catch 处理程序中构造 StackTrace 类的实例,如果我传递 Exception 对象,调用堆栈也很短。相反,如果我只调用不带参数的 new StackTrace(),它会产生一个完整的调用堆栈。

我曾使用 Reflector 尝试调试抛出异常类的内部结构并构造它的调用堆栈,但我无法在 Exception 或 StackTrace 中设置断点。我可以在 Environment.GetStackTrace() 中设置它们,并且这个方法(异常调用)在构造和抛出过程中似乎没有被调用,但我不知道调试器是否真的正常工作。(不过,这个方法确实会因为其他一些事情而被触发,所以我不知道该怎么做。)

以下是该方法的摘录:

这真的很简单:抛出异常,捕获并记录它。

无论是在调试器中还是在独立运行时(单行调用堆栈),我都会得到相同的结果。而且我知道我在我们的代码库的其他地方也看到过这个问题。以前我认为这是由于重新抛出异常,但在很多情况下,我们直接在初始 catch 块中记录。我很困惑,我所做的所有网络搜索都没有产生任何结果。


作为对提供的答案的评论,这有点太多了,但这里有一些更多信息:

我现在看到在 http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/上讨论了这种行为,并且实际上在http://msdn.microsoft 上进行了描述。 com/en-us/library/system.exception.stacktrace.aspx(尽管我认为人们很容易错过他们在那里所说的内容)。

所以我想我的“解决方案”会有点失败。我们有一个中心方法,我们通常调用它来格式化异常。在该方法中,我将创建一个带有和不带有 Exception 对象的新 StackTrace()。然后,我将查找位于异常堆栈跟踪底部的方法,并在 new StackTrace() 中显示该方法下方的所有内容,表明它是由该系列调用调用的。

当然,不利的一面是,如果不使用此方法,则信息将不存在。但我不得不期待某处的某种代码更改。

0 投票
2 回答
892 浏览

c# - 获取调用方法的方法?

是否可以在 PostError 中确定调用方法名称“Eat Pizza”?我想我可以将“EatPizza”作为参数之一传递,但是每次方法名称更改时都需要更改(不必要的维护)。但是,我什至无法在“EatPizza”的上下文中找到方法名称“EatPizza”(使用 stacktrace、getframe、getmethod)。

当我在 StackTrace.GetFrame 中尝试不同的值(0 到 StackTrace.FrameCount-1)时,我得到以下值,而我只想要“EatPizza”:

0 投票
1 回答
96 浏览

reflection - 反映一个属性的 5 个级别?

我已经实现了一个用于 Enterprise Library 5 的 CustomTraceListener。从 TraceData 方法中,我需要将堆栈爬上 6 层到我的具有实际日志记录调用的类,我需要从那里获得一个属性。我不认为我想要 StackFrame 爬升,因为那只会获取类而不是对象,对吗?获得我需要的(字符串)属性的最佳方法是什么?

这是在框架 4.0 上,谢谢。

0 投票
3 回答
42694 浏览

assembly - 进入和离开大会?

我正在阅读《汇编语言的艺术》(Randall Hyde,Amazon 的链接),并在那本书中试用了一个控制台应用程序。这是一个使用 Win32 API 函数为自己创建新控制台的程序。该程序包含一个名为 的过程LENSTR,它将字符串的长度存储在EBP寄存器中。该函数的代码如下:

你能在这里解释一下enterandleave命令的用法吗?

0 投票
4 回答
12759 浏览

assembly - "enter" vs "push ebp; mov ebp, esp; sub esp, imm" 和 "leave" vs "mov esp, ebp; pop ebp"

enter和有什么区别

指示?有性能差异吗?如果是这样,哪个更快,为什么编译器总是使用后者?

leave_

指示。

0 投票
2 回答
1973 浏览

c# - 记录文件名,日志中的行号。我需要通过 StackFrame 吗?

目前,我通过 StackFrame 来获取当前文件/行号:

Log 类中的位置是:

我是否需要每次都将 StackFrame 传递给 Log.Message() 方法?这可以在它自己的方法中完成而不通过它吗?有没有更简单的方法?

谢谢。

0 投票
1 回答
3841 浏览

gcc - 为什么 GCC 会在 64 位上丢弃帧指针?

默认情况下在 64 位架构上丢弃帧指针的基本原理是什么?我很清楚它可以启用,但为什么 GCC 在启用 32 位时首先禁用它?毕竟,64 位的寄存器比 32 位 CPU 多。

编辑:

看起来当使用更新的 GCC 版本时,x86 的帧指针也会被丢弃。从手册:

从 GCC 版本 4.6 开始,32 位 Linux x86 和 32 位 Darwin x86 目标的默认设置(未优化大小时)已更改为 -fomit-frame-pointer。可以通过使用configure 选项-fno-omit-frame-pointer配置 GCC来恢复默认值。--enable-frame-pointer

但为什么?

0 投票
3 回答
1206 浏览

smalltalk - Smalltalk 如何操作调用堆栈帧(thisContext)?

Smalltalk 对象thisContext看起来奇怪而奇妙。我无法理解它是什么以及它是如何工作的。甚至它是如何实现延续的。

对于 C 的调用堆栈,我可以很容易地想象它是如何实现和工作的。但是对于这个……我不能。请帮助我理解它。

0 投票
1 回答
432 浏览

java - 如何使用 Eclipse Java 调试器查看其他堆栈帧中的实例变量?

当我在 Eclipse 调试器下的 Java 应用程序中处于断点时,我单击堆栈框架列表中的另一个框架(在同一线程上),希望能够查看我的一些变量。只有一个变量this,当我揭示它包含的内容时,它似乎除了我认为是特殊的运行时变量之外什么都没有,例如blockerblockerLockcontextClassLoaderdaemonme(似乎只是this)等。

我想看到的是我的一个对象的实例变量。我在这里误解了调试器吗?