我打开了一个进程(使用C++/Windows)
if( CreateProcessA( NULL, // No module name (use command line)
(LPSTR)path, //argv[1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
creationFlags, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&startInfo, // Pointer to STARTUPINFO structure
&processInfo ) // Pointer to PROCESS_INFORMATION structure
Run Code Online (Sandbox Code Playgroud)
哪里
DWORD creationFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
Run Code Online (Sandbox Code Playgroud)
然后我试着用它来堆积它
bool ok = StackWalk64(IMAGE_FILE_MACHINE_I386,m_ps.Handle ,m_th.Handle,
&m_stackframe, &m_threadContext, …Run Code Online (Sandbox Code Playgroud) 我正在研究一个类,我想用它来记录Windows Vista/7计算机上的当前Call Stack.(非常类似于"行走书架" http://www.codeproject.com/Articles/11132/Walking-the-callstack).
首先,我使用RtlCaptureContext获取当前上下文记录,然后使用StackWalk64获取单个堆栈帧.现在,我意识到每当我关闭程序并重新启动时,STACKFRAME64.AddrPC中的程序计数器实际上会针对特定代码行进行更改.出于某种原因,我认为只要我不更改源代码并重新编译它,特定代码行的PC地址就会保持不变.
我需要PC-Address使用SymFromAddr和SymGetLineFromAddr64来获取有关被调用函数,代码文件和行号的信息.不幸的是,只有程序调试数据库(PDB-File)存在才能工作,但我不允许将其提供给客户端.
我的计划是记录调用堆栈的PC地址(只要需要),然后从客户端发送给我.这样我就可以使用我的PDB文件来找出调用了哪些函数,但这当然只有在PC-Addresses是唯一标识符时才有效.由于每次启动程序时它们都会改变,我不能使用这种方法.
您是否知道更好的方法来读取调用堆栈或克服更改程序计数器的问题?
我认为一种可能的解决方案可能是始终获取已知位置的PC地址并将其用作参考来仅确定不同PC地址之间的偏移量.这似乎有效,但我不确定这是否是一个有效的方法,并将始终有效.
非常感谢您的帮助!我将在codeproject.com上发布最终(封装的)解决方案,如果你喜欢,我会说你帮了我.
我可以使用当前的堆栈跟踪来检索,Thread.currentThread().getStackTrace()但是这只给出了调用中涉及的类.是否可以检索调用跟踪中涉及的对象实例?也许某种类型的库允许我从堆中检索对象?
我有一个问题,需要我追溯到一个Spring bean,间接创建了我正在请求堆栈跟踪的对象.
更新 如果在Java中没有内置工具,我正在搜索可以在运行时为我执行此操作的可嵌入库.
callstack符号表示什么?我对如何分析callstack有点了解,但我从未理解这些符号的用途.

在C中进行函数调用时,参数以相反的顺序传递.这很重要,这样我们就可以访问第一个参数.而这一些如何支持varargs.我不明白即使你有权访问第一个参数,你仍然需要知道函数有多少个参数,否则你可能很容易忽略最后一个参数并开始将无效值视为参数.
如果参数count是必需的,那么以相反的顺序传递参数是没有意义的,因为你可以使用(sp - 2*number_of_arguments,sp = stack pointer)访问第一个参数.
以相反的顺序传递参数也应该有助于递归调用,我不明白如何.
先感谢您.
看着调用堆栈我刚才注意到了这一点:

请注意Opt.out顶部.
只是好奇,什么Opt.out意思?
这是我要介绍的片段:
function BinaryEquals(Left, Right: pointer; Size: integer): boolean;
....
{$IFDEF CPUX64}
asm
....
sub r8,4
@loop1:
inc R8
Run Code Online (Sandbox Code Playgroud) 我有一个asp.net应用程序,崩溃了.在包含此callstack的Windows事件日志中有一个条目:
Exception type: EntryPointNotFoundException
Exception message: Entry point was not found.
at ***.Interfaces.Portal.Repository.ILookup.get_LookupDataCollection()
at ***.Portal.Repository.Lookup.GetLookUpValue(ILookup lookup, Int32 index)
at ***.Portal.Repository.Lookup.GetLookUpValue(ILookup lookup)
at ***.HttpModules.RuntimeHttpModule.SetPageUrlInfoInContext(PageUrlInfo pinfo)
at ***PortalRuntime.HttpModules.RuntimeHttpModule.BeginRequest(Object sender, EventArgs e)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Run Code Online (Sandbox Code Playgroud)
这只发生在客户机器上,我无法在本地重现它.正如您在顶部看到的那样,有一个接口(ILookup实际上是一个接口,而不是一个类).
我构建了一个类似的示例(通过接口调用的方法).Visual Studio 2015非常智能,可以显示:
ConsoleApplication2.exe!ConsoleApplication2.Lookup.GetLookupId(ConsoleApplication2.ILookup lookup) Line 37 C#
Run Code Online (Sandbox Code Playgroud)
但是你仍然可以看到实现该方法的类.当应用程序位于通过接口调用的方法中的断点时,我还使用windbg附加到我的示例并打印堆栈:接口不在堆栈中.
这是我的问题:
在clr callstack中查看接口是否正常(特别是没有实现它的类)?我想我以前从未见过这样的一个callstack ......其他人?(我的意思是这一般,不管我的问题的第二部分)
这是一个非常相似的问题:@Hans Passant在他的第一条评论中说"未能解决接口方法的实现方法",OP说"你已经用你的第一条评论回答了我的问题".这真的是根本原因吗?有谁知道修复此问题?或者它只是一个特殊的CLR版本?
有一个库用一些参数调用我的方法.我想收到另一个参数,但是库没有将它提供给它调用的方法.
通过反编译库,我可以看到它有参数,并且它被分配给一个实例变量(不是私有的,但也不是公共的.)我知道如果我有实例,我可以使用反射获取变量,但是我不知道也没有实例.
有没有办法可以获得实例?SecurityManager有getClassContext(),但这只是给我实例的类 - 我想要实例本身.
作为我想要的一个简单例子:
public class A {
int b;
public A(int b, int c) {
this.b = b;
D(c);
}
}
public class D {
public D(int c) {
// Somehow I want to get at the calling instance of A's b from here,
// and A belongs to a library which I didn't write.
}
}
Run Code Online (Sandbox Code Playgroud)
或者......我知道b在callstack上用作参数.因此,如果有人知道如何访问b传递给A构造函数的内容,那将是可以接受的.
如果这些都不可行......我可以A按照我想要的方式进行反编译和编译,然后我需要做一些类加载魔法或者我必须修改jar的内容.这些都不合适,所以我希望有人知道如何从调用堆栈访问实例A或参数b.
我想在Native C++应用程序中运行时访问调用堆栈.我没有使用IDE.如何显示调用堆栈?
更新:我有一个函数,从整个应用程序的许多点调用.它在极少数情况下崩溃.我正在寻找一种方法来获取调用者的名字并记录它.
我想实现通用记录器,它可以帮助我查看方法的调用堆栈。
我知道 System.Diagnostic 有一些方法,但它们是在 .net 4.0 中引入的,恐怕它不适用于 xamarin 或 .net core 或类似的东西。所以我想要更通用的解决方案。
另一个问题是 async\await,它会带来一些混乱。
我通过在每个方法中传递附加参数来存储一些上下文并帮助我确定调用堆栈,但是这个解决方案有点复杂。
我也可以使用不安全代码读取线程堆栈内存并自己检查调用堆栈,但它不可靠。
还有其他解决方案吗?
callstack ×10
debugging ×4
stack-trace ×3
c# ×2
c++ ×2
java ×2
windows ×2
.net ×1
c ×1
clr ×1
delphi ×1
delphi-xe7 ×1
function ×1
interface ×1
ios ×1
logging ×1
objective-c ×1
reflection ×1
stack ×1
visual-c++ ×1
xcode ×1