是否可以抑制第三方DLL的详细调试输出?我的调试输出窗口充满了它们。我无法修改有问题的DLL。
答案 0 :(得分:3)
我认为没有任何简单的方法可以做到这一点。
一种方法是以任何方式工作 API挂钩(或功能挂钩)。如何做到这一点有不同的方式。
如果您要在其中拒绝调试输出导入OutputDebugString
函数的DLL(使用dumpbin /imports thedll.dll
),可以修补PE导入地址表(IMAGE_THUNK_DATA
)内存中的DLL指向你的虚函数的引用,它什么都不做。
如果您不确切知道第三方DLL使用的是哪种API,则可以使用代码覆盖技术,以便OutputDebugString
的代码在您的进程内存中运行将被更改(JMP或CALL指令),以便您的函数将被调用,您的代码可以检查调用堆栈,如果第三方DLL在里面,您将无能为力。如果您在调用堆栈中未找到第三方DLL,则可以将调用转发到OutputDebugString
的原始实现。
两种描述技术都用于DLL注入。在您的情况下,您需要更简单的案例,因为您需要在自己的流程中进行更改,因此不需要特殊的用户权限。
所有描述的技术并不像我在答案开头所写的那样简单。我在回答的开头写道,我认为不存在任何简单的方法。另一方面,您不需要自己实现上述所有内容。您可以在Internet上以多种计算机语言找到足够的代码示例。
答案 1 :(得分:2)
我不这么认为,因为调试输出跟踪记录没有所有者。
如果流氓痕迹显示某些模式,您可以使用类似于DebugView的开源工具过滤掉这些模型我为此类问题写的:TraceSpy,但在这种情况下,您将会需要可视化Visual Studio外部的跟踪。它不会改变OutputWindow的行为。
答案 2 :(得分:1)
有一种非常简单的方法可以实现这一点,请联系原始开发人员并要求他们为您提供一个构建为Release而不是Debug的DLL。只需翻转该开关就会关闭所有消息,因为Debug.Xxxx()方法都会在每个程序集的发布编译中得到优化。
答案 3 :(得分:0)
我不知道您是否可以直接有条件地过滤消息。
但是你可以调用System.Diagnostics.Debug.Listeners.Clear()作为main()中的第一个语句,它基本上不会为正在运行的会话打印任何内容。
答案 4 :(得分:0)
如果使用WinDbg(提供比VS调试器更多的可能性)进行调试,则可以使用“.ofilter”命令来抑制特定消息或可能的事件过滤器来抑制模块发出的所有消息。 如果你真的想使用visual studio,你可以(至少在2010版本中)在“立即窗口”中直接发出WinDbg命令,虽然我不确定.ofilter命令是否可用 - 我在这里快速尝试了它并没有'工作,但也许值得一试。
答案 5 :(得分:0)
如果在traceListener中进行过滤怎么办?
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Debug.WriteLine("Hello world");
Debug.Listeners.Clear();
var listener = new FilteringListener();
listener.IgnoredAssemblies.Add("ConsoleApplication1");
Debug.Listeners.Add(listener);
Debug.WriteLine("Goodbye");
Console.Read();
}
}
}
namespace ConsoleApplication1
{
public class FilteringListener : System.Diagnostics.TraceListener
{
public FilteringListener()
{
IgnoredAssemblies = new List<string>();
_inner = new DefaultTraceListener();
}
private DefaultTraceListener _inner;
public List<String> IgnoredAssemblies { get; private set; }
public override void Write(string message)
{
if (ShouldFilter())
_inner.Write(message);
}
private bool ShouldFilter()
{
var stack = new StackTrace();
var stackFrame = stack.GetFrame(4);
var method = stackFrame.GetMethod();
var assembly = method.DeclaringType.Assembly;
return !IgnoredAssemblies.Any(x => assembly.FullName.Contains(x);
}
public override void WriteLine(string message)
{
if (ShouldFilter())
_inner.WriteLine(message);
}
}
}
当然,这种实现的问题是要求调用新监听器的内部工作不会改变,因此堆栈偏移量4仍然有效。但由于这仅适用于您的调试输出,至少您会引入生产错误,只会再次出现错误的跟踪输出。