首先,问题是: 我有几个免费项目,并且任何软件都包含bug.一些用户在遇到bug时会向我发送一个带有堆栈跟踪的bug报告.为了简化查找故障位置,我想在此堆栈跟踪中查看行号.如果应用程序没有.pdb文件,那么所有行信息都会丢失,因此目前我的所有项目都部署了.pdb文件,因此生成的堆栈跟踪具有此数字.但!但我不希望在发行版中看到这些文件,并希望删除所有.pdb.它们会混淆用户,消耗安装程序中的空间等.
Delphi解决方案: 很久以前当我是delphi程序员时,我使用了以下技术:例外我的应用程序在堆栈上行走并收集地址.然后,当我收到错误报告时,我使用了一个工具,根据收集的地址和位于MY机器上的相应符号文件,使用函数名称和行号重建有效的堆栈跟踪.
问题: 在.NET中是否有任何lib,或技术或其他任何相同的操作?
状态更新:非常有趣,经常提出问题是开始自己调查的最佳方式.例如,我想了一段时间这个问题,但几天前才开始寻找答案.
选项1:MiniDumps.经过大量的谷歌搜索后,我找到了一种从代码创建迷你转储的方法,以及如何从托管小型转储中重新创建堆栈.
然而,该解决方案需要重新分配两个额外的组件(大小约为1mb),并且小型转储占用一些空间,并且用户通过电子邮件发送它们是不舒服的.所以对于我的目的,现在,这是不可接受的.
选项2:感谢weiqure的线索.可以为每个堆栈帧提取受管理的IL偏移量.现在问题是如何根据此偏移从.pdb获取行号.我发现了什么:
使用此工具,可以为每个发布版本创建xml文件并将它们放入repositary.当用户的机器上发生异常时,可以创建带有IL偏移的格式化错误消息.然后用户通过邮件发送此消息(非常小).最后,可以创建一个简单的工具,从格式化的错误消息重新创建结果堆栈.
我只是想知道为什么没有其他人没有实现这样的工具?我不相信这只对我有意义.
我有一个不寻常的情况,我有一个非常简单的异常被抛出并被相同的方法捕获. 它不会被重新抛出(天真的程序员常常遇到的问题).然而它的StackFrame只包含一个当前方法.这是它的样子:
at (my class).MyMethod() in C:\(my file path and line)
Run Code Online (Sandbox Code Playgroud)
实际上,在VS2010调试器的调用堆栈中,可能有30种方法可以实现这一点,它涉及六个不同的程序集.似乎不可能对所有人进行优化.此外,对于.NET 4 ,此代码是在调试模式下构建的,没有优化.我甚至(基于http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx).ini文件(包括一个)命名为[app] .vshost.ini)在同一文件夹中包含:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
Run Code Online (Sandbox Code Playgroud)
此外,方法调用不在方法的末尾,因此尾递归优化似乎更不可能.
至于如何调用它:在调用堆栈上没有反射的使用,没有任何类型的Invoke()或BeginInvoke().这只是一个按钮点击的长链调用.点击处理程序大约是调用堆栈的10次调用.在它之下你有通常的WndProc,NativeWindow.Callback,本机/托管转换和消息循环.这最终是在一个从C#EXE程序集运行的ShowDialog()调用中.
现在,我发现我可以在catch处理程序中构造StackTrace类的实例,如果我传递Exception对象,则调用堆栈也很短.相反,如果我只调用没有参数的新StackTrace(),它会产生一个完整的调用堆栈.
我已经使用Reflector试图调试Exception类的内部被抛出并构造它的调用堆栈,但是我无法在Exception或StackTrace中设置断点.我可以在Environment.GetStackTrace()中设置它们,并且这个方法(Exception调用)似乎在构造和抛出过程中不会被调用,但我不知道调试器是否真的正常工作.(虽然这个方法确实被其他一些东西触发了,所以我不知道该怎么做.)
以下是该方法的摘录:
private void MyMethod()
{
...
try
{
throw new ApplicationException("Test failure");
}
catch (Exception e)
{
StackTrace stackTrace1 = new StackTrace(e);
StackTrace stackTrace2 = new StackTrace(e, false);
StackTrace stackTrace3 = new StackTrace(e, true);
StackTrace stackTrace4 = new StackTrace();
string STs = stackTrace1.ToString() + "\n---\n"
+ stackTrace2.ToString() + …Run Code Online (Sandbox Code Playgroud) 我想在beta测试期间记录项目中的所有JS错误.现在我用以下方式做到:
window.onerror = myErrHandler;
function myErrHandler(message, url, line)
{
$.ajax({
cache: false,
type: "post",
data: {error:message, url:url, line:line, brouser:navigator.userAgent},
url: "/Home/LogJavaScript/",
async: true
});
return true;
}
Run Code Online (Sandbox Code Playgroud)
但这种方式无法获得有关调用堆栈的任何信息.因此,有关jQuery或任何其他外部脚本中的错误的信息无济于事.
有没有办法改善这种日志记录?
这个问题很可能重复使用来自Cygwin可执行文件的stackdump - 但我是初学者,我不理解答案,甚至是部分问题.
我是c ++和编程的新手,我在NetBeans中开发.我正在编写一些编译得很好的代码,但是在运行时失败了.如果我使用调试器,我会收到以下错误:
1 [main] all 6200 exception::handle: Exception: STATUS_ACCESS_VIOLATION
881 [main] all 6200 open_stackdumpfile: Dumping stack trace to all.exe.stackdump
Run Code Online (Sandbox Code Playgroud)
我已经设法找到文件all.exe.stackdump,我可以通过记事本++阅读它,但我不明白这是什么意思.我通过另一个问题收集到有一种用户友好的方式来解码这个文件,但我最好的猜测bash$ gdb all.exe.stackdump是无效的.在调试中使用此文件的最佳方法是什么?
为了防止它有用,这里是all.exe.stackdump的内容
Exception: STATUS_ACCESS_VIOLATION at eip=00434C41
eax=2003A2E4 ebx=0028A95C ecx=00000000 edx=0028A95C esi=0028A9B0 edi=00000000
ebp=0028A9C8 esp=0028A930 program=[redacted for privacy/security], pid 6200, thread main
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
0028A9C8 00434C41 (00000000, 2003A4F0, 0028A9E8, 00000000)
0028A9E8 00436B14 (00000000, 2003A4F0, 0028AA28, 0028D000)
0028AAF8 004036A4 (0028AB80, 2003A2B0, 00000014, 00000003)
0028ABD8 00403FBC (00000001, …Run Code Online (Sandbox Code Playgroud) 我的问题是:是否有可能(以任何方式)在运行时分析和修改调用堆栈(帧内容和堆栈内容)?
我正在寻找任何可能性 - 低级,不安全或内部API,编写C扩展的可能性等.只有约束:它应该可以在标准运行时使用,无需调试或分析模式.这就是我正在研究"它有可能吗?",而不是"这是好主意吗?".
我想从一个框架中收集所有本地数据,将其存储在某个地方,然后从堆栈中删除该框架,以后可以恢复它.实际上,它为我们提供了JVM的延续,它们将允许快速异步框架(如来自python的gevents)和生成器结构(如python中的那些).
这可能看起来像重复的问题,但我只发现了用"使用Thread.currentThread().getStackTrace()"或"应该用调试工具完成"的问题.我有类似的问题,但它只是在询问人们想要做什么(处理异步计算)的背景下回答,而我需要更一般的(面向Java堆栈)答案.这个问题也是类似的,但和以前一样,它专注于并行化,答案也集中于此.
我再说一遍:这是提出新语言功能提案的研究步骤.我不想冒险破坏JVM中的任何东西 - 我正在寻找可能性,然后我将分析可能的风险并留意它们.我知道手工操作堆栈是丑陋的,但是通过省略的consrtuctor创建实例也是如此 - 它是客观化的基础.肮脏的黑客可能很脏,但它们可能有助于引入一些很酷的东西.
PS.我知道Quasar和Lightwolf存在,但是,如上所述,那些是以并发为中心的框架.
编辑
澄清一点:我正在寻找与未来JVM和库版本兼容的东西.我们最好谈论一些被认为是稳定的公共API的东西,但如果解决方案存在于内部,但几乎是标准的,或者在内部(如sun.misc.Unsafe)之后成为标准的东西 - 这也会做.如果C-extension只使用C JVM API可行 - 那没关系.如果这对于字节码操作是可行的 - 那也没关系(我认为可以使用ASM).
有没有办法看到什么超时,间隔或异步操作(或无限循环)仍在运行,并阻止我的进程结束?
到目前为止,我已经能够在没有这样的工具的情况下解决这个问题,但是这样的工具非常方便,尤其是当Node.JS项目开始变大时.
我在想Java kill -3,它将堆栈跟踪打印到stderr.您可以为任何进程,任何时间,调试或否执行此操作.我想要Node.JS的等价物.(我知道该节点是单线程的异步,因此输出方式不同)
我可以通过StackTrace获取有关参数的信息,使用类似的方法:
catch (Exception ex)
{
var st = new StackTrace(ex);
System.Reflection.ParameterInfo pi = st.GetFrame(0).GetMethod().GetParameters().First();
}
Run Code Online (Sandbox Code Playgroud)
我想知道我如何获得参数的值.例:
如果我在堆栈跟踪中的方法是这样的:
void MyMethod(object value)
Run Code Online (Sandbox Code Playgroud)
电话就像:
MyMethod(10);
Run Code Online (Sandbox Code Playgroud)
我想得到价值10.我怎么做?
<init>在Java异常中表示什么?
例如:
BlahBlahException...
at java.io.FileInputStream.<init>(FileInputStream.java:20)
Run Code Online (Sandbox Code Playgroud) 我们最近有一种情况,我们的一个生产JVM会随机冻结.Java进程正在烧毁CPU,但所有可见活动都将停止:没有日志输出,没有写入GC日志,没有响应任何网络请求等.进程将保持此状态直到重新启动.
原来,该org.mozilla.javascript.DToA类,某些输入调用时,会感到困惑,并呼吁BigInteger.pow着巨大的值(例如5 ^ 2147483647),这会触发JVM冻结.我的猜测是,一些大循环,可能是在java.math.BigInteger.multiplyToLen中,在循环中没有安全点检查的情况下进行了JIT.下次JVM需要暂停进行垃圾收集时,它会冻结,因为运行BigInteger代码的线程很长时间都不会达到安全点.
我的问题:将来,我如何诊断这样的安全点问题?杀-3没有产生任何输出; 我认为它依赖于安全点来生成准确的堆栈.是否有任何生产安全的工具可以从正在运行的JVM中提取堆栈而无需等待安全点?(在这种情况下,我真的很幸运,并设法抓住一组堆叠的痕迹BigInteger.pow被调用刚过,但在此之前它的工作它的方式到足够大的输入完全楔入JVM,没有运气中风,我我不确定我们怎么会诊断出这个问题.)
编辑:以下代码说明了问题.
// Spawn a background thread to compute an enormous number.
new Thread(){ @Override public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
BigInteger.valueOf(5).pow(100000000);
}}.start();
// Loop, allocating memory and periodically logging progress, so illustrate GC pause times.
byte[] b;
for (int outer = 0; ; outer++) {
long startMs = System.currentTimeMillis();
for (int inner = 0; inner < 100000; inner++) {
b = new byte[1000];
}
System.out.println("Iteration " …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个函数,该函数将在引发对象常量时重新引入堆栈跟踪。(请参阅此相关问题)。
我注意到的是,如果将异步函数作为回调传递给另一个异步调用者函数,则如果调用者函数具有try / catch并捕获任何错误并抛出新的Error,则堆栈跟踪会丢失。
我已经尝试了几种方法:
function alpha() {
throw Error("I am an error!");
}
function alphaObectLiberal() {
throw "I am an object literal!"; //Ordinarily this will cause the stack trace to be lost.
}
function syncFunctionCaller(fn) {
return fn();
}
function syncFunctionCaller2(fn) { //This wrapper wraps it in a proper error and subsequently preserves the stack trace.
try {
return fn();
} catch (err) {
throw new Error(err); //Stack trace is preserved when it is synchronous.
}
} …Run Code Online (Sandbox Code Playgroud) stack-trace ×10
.net ×3
c# ×3
exception ×3
debugging ×2
java ×2
javascript ×2
jvm ×2
async-await ×1
c++ ×1
freeze ×1
jit ×1
jquery ×1
logging ×1
node.js ×1
stack-dump ×1
stack-frame ×1
try-catch ×1