需要通过线程句柄打印 C++ 应用程序线程的调用堆栈,我转向了之前的 stackoverflow 答案中提到的StackWalker 。
然而,StakWalker 代码的日期是 2005 年。我怀疑从那时起有些东西发生了变化。
当我编译并运行它时,出现错误(如下),并且输出似乎不完整,在错误时被截断。测试应打印更多测试用例。
有人有更新的或不同的工作调用堆栈打印已发布的代码吗?
e:\boris\stackwalker\stackwalker\main.cpp (31): Func5
e:\boris\stackwalker\stackwalker\main.cpp (32): Func4
e:\boris\stackwalker\stackwalker\main.cpp (33): Func3
e:\boris\stackwalker\stackwalker\main.cpp (34): Func2
e:\boris\stackwalker\stackwalker\main.cpp (35): TestCurrentThread
e:\boris\stackwalker\stackwalker\main.cpp (139): main
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (582): __tmainCRTStartup
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (399): mainCRTStartup
VVVVV
ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 7C817077)
^^^^^
7C817077 (kernel32): (filename not available): RegisterWaitForInputIdle
Run Code Online (Sandbox Code Playgroud) 我有一个实用方法来计时和记录整个项目中的各种查询。问题是,crashlytics现在看来,所有不相关的崩溃都被合并到一个崩溃实例中。
我可以捕获实用程序方法上的所有异常,并在从堆栈中删除该方法后抛出它们吗?
环境是Android(Java)
更新:
根据下面@Dhananjay 的回答,这是我的代码:
public static Cursor get(...) {
try {
// my utility code
} catch (RuntimeException e) {
throw cleanException(e);
}
}
private static RuntimeException cleanException(RuntimeException e) {
try {
StackTraceElement[] stackTrace = e.getStackTrace();
StackTraceElement[] subTrace = new StackTraceElement[stackTrace.length - 1];
System.arraycopy(stackTrace, 1, subTrace, 0, subTrace.length);
e.setStackTrace(subTrace);
return e;
} catch (Throwable ignored) {
return e;
}
}
Run Code Online (Sandbox Code Playgroud) 当捕获非法参数异常时,dangerousMethodHandler() 会从 StackTraceElement 数组打印错误的堆栈跟踪。对于任何其他类型的异常,dangerousMethodHandler() 会打印“Exception!”
我目前已经解决了其他异常,但似乎无法使用 StackTraceElemen 数组实现我的代码
public void dangerousMethod() {
Character.toChars(~0);
}
public void dangerousMethodHandler() {
try {
this.dangerousMethod();
}catch(IllegalArgumentException e){
StackTraceElement[] trace = e.getStackTrace();
e.getStackTrace();
System.err.println(trace[0].toString());
} catch (Exception e){
System.out.print("Exception!");
}
}
Run Code Online (Sandbox Code Playgroud)
当我打印出以下内容时我得到
java.lang.Character.toChars(Character.java:4982)
Run Code Online (Sandbox Code Playgroud)
我的输出应该是:
java\.lang\.Character\.toChars\(Character\.java:\d+\)[\s\n]+Main\.dangerousMethod\(Main\.java:\d+\)[\s\n]+Main\.dangerousMethodHandler\(Main\.java:\d+\)[\s\n]+Main\.runTests\(Main\.java:\d+\)[\s\n]+Main\.main\(Main\.java:\d+\)
Run Code Online (Sandbox Code Playgroud) 通常,当我使用 Debug.Log() 打印某些内容时,它会显示在控制台中,我可以双击它来转到函数调用。此外,单击一下即可展开文本以公开一种调用历史记录(某个函数调用另一个函数,另一个函数调用另一个函数,依此类推。直到调用 Debug.Log() 为止)。
但现在我只得到这种奇怪的行为,其中函数调用被堆栈的内存地址替换。
我还无法发布图像,所以这是控制台的样子
我仍然可以通过展开消息来找到呼叫发生的位置,但这是一场噩梦
你能找到电话吗?提示:它来自 PointCloudGenerator.cs 第 290 行
情况不会那么糟糕,但问题是双击行为根本不起作用,并且尝试找出调用的来源非常令人沮丧。警告和错误也会发生完全相同的情况。
编辑:我正在使用 Unity 5.6.3p3,我的编辑器是 Visual Studio 2017 Enterprise
这是调用日志的地方:
private IEnumerator ReadCornerData(long capacity, CloudBounds cloudBounds)
{
List<Vector3> corners = new List<Vector3>();
List<Vector3> borders = new List<Vector3>();
using (MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateOrOpen("Global\\CornerData", capacity, MemoryMappedFileAccess.ReadWrite))
{
using (MemoryMappedViewAccessor accessor = memoryMappedFile.CreateViewAccessor())
{
byte dataAvailable = 0;
accessor.Write(0, ref dataAvailable);
accessor.Write((int)capacity / 2, ref dataAvailable);
int memIndex = 0;
while (dataAvailable != 0xF)
{
accessor.Read(memIndex, out dataAvailable);
yield return …Run Code Online (Sandbox Code Playgroud) Thread.getStackTrace()返回StackTraceElement[]。如何将其转换为String与返回格式相同的a Exception.printStackTrace()?
澄清一下:我没有例外,只有一个线程。我想使用与异常堆栈跟踪相同的格式显示线程的堆栈跟踪。
我正在查看在 F# 中生成的堆栈跟踪,它们正在跳过函数。一个测试用例:
let foo() =
failwithf "foo"
[<EntryPoint>]
let main argv =
foo()
0
Run Code Online (Sandbox Code Playgroud)
使用调试信息编译,并运行:
(torch) C:\t>fsc -g test.fs
Microsoft (R) F# Compiler version 10.8.0.0 for F# 4.7
Copyright (c) Microsoft Corporation. All Rights Reserved.
(torch) C:\t>test
Unhandled Exception: System.Exception: foo
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1637.Invoke(String message)
at Test.main(String[] argv) in C:\t\test.fs:line 7
Run Code Online (Sandbox Code Playgroud)
它说异常是从 生成的main,没有提到foo它实际生成的位置。
如何获取完整的堆栈跟踪,包括实际生成异常的函数?
我正在读取 go 程序的堆栈跟踪以进行调试。
goroutine 6 [chan receive]:
go.elastic.co/apm.(*Tracer).loop.func2(0xc000042420, 0xc0000423c0, 0x1551980, 0xc0004da100, 0xc000074300, 0xc000001080, 0xc00000e018)
/app/vendor/go.elastic.co/apm/tracer.go:803 +0x21a
created by go.elastic.co/apm.(*Tracer).loop
/app/vendor/go.elastic.co/apm/tracer.go:800 +0x36e
goroutine 8 [chan receive, 21 minutes]:
github.com/getsentry/sentry-go.(*HTTPTransport).worker(0xc0003025b0)
/app/vendor/github.com/getsentry/sentry-go/transport.go:387 +0x77
created by github.com/getsentry/sentry-go.(*HTTPTransport).Configure.func1
/app/vendor/github.com/getsentry/sentry-go/transport.go:255 +0x3e
Run Code Online (Sandbox Code Playgroud)
21 minutes第二个 go 例程中的时间意味着什么?这次没有第一次。我查阅了文档,但找不到这个时间的用途。
在javascript中,我可以使用foo.caller在堆栈跟踪中获取对foo之上的函数的引用.但是,当函数在同一堆栈跟踪中多次出现时,这不起作用,foo.caller只返回foo.
是否有一种稳定的,跨平台的方法来获取Javascript中的完整堆栈跟踪?我不希望得到一个可打印的堆栈跟踪; 相反,我正在进行堆栈检查以查看某个方法是否位于堆栈中的任何位置.这是我目前的代码:
function inFunction(foo) {
var caller = inFunction.caller;
var maxDepth = 20;
while(caller && --maxDepth > 0) {
if(caller == foo)
return true;
caller = caller.caller;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
任何想法如何处理堆栈跟踪中多次存在的函数?
将throwable/exception的整个堆栈跟踪转换为ByteBuffer(在Java中)的最有效方法是什么?
具体来说,我需要将整个异常记录到数据库中.Thread.currentThread().getStackTrace()返回StackTraceElement []数组的列表.
然后,Throwable类中有一个printStackTrace()方法?
我正在研究一个方面方面,需要知道它从哪里调用.目前我正在使用
new Throwable().getStackTrace();
Run Code Online (Sandbox Code Playgroud)
访问此信息,但每个方面需要几百微秒才能运行.
我看过SecurityManager,但似乎只能得到我的类名.
还有其他我错过的选择吗?
更新
JMH基准测试结果在我对@ apangin答案的评论中提到:
Benchmark Mode Cnt Score Error Units
MyBenchmark.javalangaccess13i avgt 100 2025.865 ± 8.133 ns/op
MyBenchmark.javalangaccess2i avgt 100 2648.598 ± 24.369 ns/op
MyBenchmark.throwable1 avgt 100 12706.978 ± 84.651 ns/op
Run Code Online (Sandbox Code Playgroud)
基准代码:
@Benchmark
public StackTraceElement[] throwable1() {
return new Throwable().getStackTrace();
}
@SuppressWarnings("restriction")
@Benchmark
public static StackTraceElement javalangaccess2i() {
Exception e = new Exception();
return sun.misc.SharedSecrets.getJavaLangAccess().getStackTraceElement(e, 2);
}
@SuppressWarnings("restriction")
@Benchmark
public static StackTraceElement javalangaccess13i() {
Exception e = new Exception();
return sun.misc.SharedSecrets.getJavaLangAccess().getStackTraceElement(e, 13);
}
Run Code Online (Sandbox Code Playgroud)
在戴尔XPS13 9343(i5-5200U …
stack-trace ×10
java ×5
exception ×3
.net ×1
android ×1
aspectj ×1
c# ×1
c++ ×1
callstack ×1
console ×1
crashlytics ×1
debugging ×1
f# ×1
go ×1
javascript ×1
performance ×1
throwable ×1
try-catch ×1
winapi ×1