我正在实现 DebugExtensionProvideValue在我的扩展中,这样我就可以提供自定义伪寄存器。它在 CDB 中完美运行,最初在 WinDbg 中运行良好,但在停止调试并打开一个新的可执行文件后,发生了一些事情,WinDbg 最终处于一种奇怪的不可用状态。
当您触发问题时,WinDbg 将此消息打印到命令窗口:
Unable to deliver callback, 3131
发生这种情况后,WinDbg 似乎会在命令窗口中打印两次所有输出!
我的扩展代码很简单:
EXTERN_C HRESULT CALLBACK DebugExtensionProvideValue(PDEBUG_CLIENT Client, ULONG Flags, IN PCWSTR Name, OUT PULONG64 Value, OUT PULONG64 TypeModBase, OUT PULONG TypeId, OUT PULONG TypeFlags)
{
HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
if (!Name || !Value || !TypeFlags)
{
hr = E_INVALIDARG;
}
else if (0 == lstrcmpiW(Name, L"$$test"))
{
*Value = 0xDeadCafeBabeBeefULL;
*TypeFlags = DEBUG_EXT_PVTYPE_IS_VALUE;
if (TypeId) *TypeId = 0; // Where are these types defined?
if (TypeModBase) *TypeModBase = 0;
hr = S_OK;
}
#if 0 // <-- ** Setting this to != 0 fixes the problem **
Client->Release(); // This does not feel right but it does seem to be required!
#endif
return hr;
}
EXTERN_C HRESULT CALLBACK DebugExtensionQueryValueNames(PDEBUG_CLIENT Client, ULONG Flags, OUT PWSTR Buffer, ULONG BufferChars, OUT PULONG BufferNeeded)
{
static const WCHAR pseregs[] = L"$$test\0";
if (BufferNeeded) *BufferNeeded = ARRAYSIZE(pseregs);
memcpy(Buffer, pseregs, min(sizeof(pseregs), BufferChars*sizeof(*Buffer)));
return ARRAYSIZE(pseregs) > BufferChars ? S_FALSE : S_OK;
}
EXTERN_C HRESULT CALLBACK DebugExtensionInitialize(OUT PULONG Version, OUT PULONG Flags)
{
*Version = DEBUG_EXTENSION_VERSION(1, 0), *Flags = 0;
return S_OK;
}
重现问题看起来像这样:
0:000> $$ Press Ctrl+E to open a executable, I'm going to open WinVer.exe
0:000> .load c:\test\myext.dll
0:000> ?@$$test
Evaluate expression: -2401039830915039505 = deadcafe`babebeef
0:000> $$ Press Shift+F5 to stop debugging
0:000> $$ Press Ctrl+E and open a executable again, WinDbg will now print "Unable to deliver callback, 3131"
我能够想出一个似乎确实有效的解决方法,但它感觉不对,因为我必须发布一个我从未 QI 或 AddRef 的接口(interface)。在我进行的最少测试中,这个 hack 似乎从来没有崩溃过,通过查看 IDebugClients refcount,它在多次调用中看起来确实是正确的。
据我所知,您无法停止调试并在 CDB 中打开一个新的 .exe,因此问题似乎只会发生在 WinDbg 中。
是我做错了什么还是 DbgEng 中有错误?
最佳答案
@安德斯
我花了一些时间在不同的代码路径中检查它,似乎在 dbgeng ClientListCapture/Find/fill/list/FindExt 中存在错误
增加的引用计数似乎没有减少,导致引用累积在每次关闭和打开时添加多个回调
我使用的代码路径是设置扩展类的 m_ProvidedValue 成员
请注意,我还添加了代码来解决下面的其他两个查询 TypeId 和 TypeModBase
#include <engextcpp.cpp>
ExtProvidedValue pval[];
class EXT_CLASS : public ExtExtension {
public:
void
handler (
_In_ ULONG Flags, _In_ PCWSTR ValueName, _Out_ PULONG64 Value,
_Out_ PULONG64 TypeModBase, _Out_ PULONG TypeId, _Out_ PULONG TypeFlags
) {
DEBUG_CACHED_SYMBOL_INFO Info;
ZeroMemory(&Info, sizeof(Info));
PCSTR Type = "ntdll!_LDR_DATA_TABLE_ENTRY";
HRESULT Status = E_FAIL;
if((Status = m_Symbols->GetSymbolTypeId(Type,&Info.Id,&Info.ModBase)) != S_OK) {
ThrowStatus(Status, "Unable to get type ID of '%s'", Type);
}
if (0 == lstrcmpiW(ValueName, L"$$test")) {
if(Value) { *Value = 0xDeadCafeBabeBeefULL; }
if(TypeModBase) { *TypeModBase = Info.ModBase; }
if(TypeId) { *TypeId = Info.Id; }
if(TypeFlags) { *TypeFlags = DEBUG_EXT_PVTYPE_IS_POINTER; }
}
};
HRESULT Initialize(void) {
this->m_ProvidedValues = pval;
return S_OK;
}
};
EXT_DECLARE_GLOBALS();
ExtProvideValueMethod mymethod = (ExtProvideValueMethod)&Extension::handler;
ExtProvidedValue pval[] = {L"$$test\0",mymethod,NULL,NULL};
def文件包含
EXPORTS
DebugExtensionInitialize
DebugExtensionQueryValueNames
DebugExtensionProvideValue
help
编译链接enterprise wdk如下
@echo off
IF "%donesetup%" == "" ( pushd .. )
IF "%donesetup%" == "" ( cd /d E:\ewdk )
IF "%donesetup%" == "" ( @call launchbuildenv.cmd )
IF "%donesetup%" == "" ( popd )
IF "%donesetup%" == "" ( set "donesetup=donesetup" )
IF "%INCLUDE%" == "" ( set "INCLUDE=%vcinstalldir%include;%windowssdkdir%Include\10.0.10586.0\ucrt;%windowssdkdir%Include\10.0.10586.0\um;%windowssdkdir%Include\10.0.10586.0\shared;%windowssdkdir%Debuggers\inc;" )
IF "%LIB%" == "" ( set "LIB=%vcinstalldir%\LIB;%WINDOWSSDKDIR%Lib\10.0.10586.0\ucrt\x86;%WINDOWSSDKDIR%Lib\10.0.10586.0\um\x86;%windowssdkdir%Debuggers\lib\x86")
IF "%LINKLIBS%" == "" ( set "LINKLIBS=user32.lib kernel32.lib dbgeng.lib dbghelp.lib" )
cl /LD /nologo /W3 /Zi /EHsc pstest.cpp /link /DEF:pstest.def /RELEASE %linklibs%
move /y pstest.dll "e:\ewdk\Program Files\Windows Kits\10\Debuggers\x86\winext"\.
加载扩展到windbg和调用结果
Microsoft (R) Windows Debugger Version 10.0.10586.567 X86
0:000> .load pstest
0:000> ? @$$test (masm Evaluate)
Evaluate expression: -2401039830915039505 = deadcafe`babebeef
0:000> ?? @$$test (c++ Evaluate note the use of TypeId and TypeModbase
results in a type Display instead of a Int64 value)
struct _LDR_DATA_TABLE_ENTRY * 0xbabebeef
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x008 InMemoryOrderLinks : _LIST_ENTRY
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x018 DllBase : ????
+0x01c EntryPoint : ????
+0x020 SizeOfImage : ??
+0x024 FullDllName : _UNICODE_STRING
+0x02c BaseDllName : _UNICODE_STRING
+0x034 Flags : ??
+0x038 LoadCount : ??
+0x03a TlsIndex : ??
+0x03c HashLinks : _LIST_ENTRY
+0x03c SectionPointer : ????
+0x040 CheckSum : ??
+0x044 TimeDateStamp : ??
+0x044 LoadedImports : ????
+0x048 EntryPointActivationContext : ????
+0x04c PatchInformation : ????
+0x050 ForwarderLinks : _LIST_ENTRY
+0x058 ServiceTagLinks : _LIST_ENTRY
+0x060 StaticLinks : _LIST_ENTRY
+0x068 ContextInformation : ????
+0x06c OriginalBase : ??
+0x070 LoadTime : _LARGE_INTEGER
如果我按 Shift+f5 和 ctrl+e,windbg 会提示它无法传递回调,正如你发布的那样
如果重复 shift +f5/ctrl+e/load/invoke 的过程
投诉的数量不断增加,导致 windbg 挂起
尝试在挂起的调用堆栈中处理 PendingMessages
关于windows - 实现 DebugExtensionProvideValue 会破坏 WinDbg 内部状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37417335/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO