You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pose库拦截Task中Debug.WriteLine遇栈溢出问题求助

问题描述

我创建了如下Shim:

using Pose;

Shim consoleShim = Shim.Replace(() => Debug.WriteLine(Is.A<string>())).With(
    delegate (string s) { Debug.WriteLine($"Hijacked: {s}"); });

以下代码可正常运行并输出“Hijacked: Test Debug”:

PoseContext.Isolate(() =>
{
    Debug.WriteLine("Test Debug");
}, consoleShim);

但以下代码执行时会触发栈溢出错误:

PoseContext.Isolate(() =>
{
    _ = Task.Run(() =>
    {
        Debug.WriteLine("In different task");
    });
}, consoleShim);

错误栈信息如下:

Stack overflow.
   at System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Int32)
   at System.Collections.Generic.Dictionary`2[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Reflection.Emit.Label, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryInsert(Int32, System.Reflection.Emit.Label, System.Collections.Generic.InsertionBehavior)
   at Pose.Extensions.DictionaryExtensions.TryAdd[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Reflection.Emit.Label, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Collections.Generic.Dictionary`2<Int32,System.Reflection.Emit.Label>, Int32, System.Reflection.Emit.Label)
   at Pose.IL.MethodRewriter.Rewrite()
   at DynamicClass.stub_System.Collections.Generic.List`1[System.String]_LastIndexOf(System.Collections.Generic.List`1<System.String>, System.String, Int32, Int32, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.Collections.Generic.List`1[System.String]_LastIndexOf(System.Collections.Generic.List`1<System.String>, System.String)
   at DynamicClass.stub_virt_System.Collections.Generic.List`1[System.String]_LastIndexOf(System.Collections.Generic.List`1<System.String>, System.String, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.SR_InternalGetResourceString(System.String)
   at DynamicClass.stub_System.SR_InternalGetResourceString(System.String, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.SR_GetResourceString(System.String)
   at DynamicClass.stub_System.SR_GetResourceString(System.String, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.stub_System.SR_get_Arg_InvalidOperationException(System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.InvalidOperationException_.ctor(System.InvalidOperationException)
   at DynamicClass.stub_ctor_System.InvalidOperationException_.ctor(System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.Runtime.CompilerServices.RuntimeHelpers_IsBitwiseEquatable()
   at DynamicClass.stub_System.Runtime.CompilerServices.RuntimeHelpers_IsBitwiseEquatable(System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.Array_LastIndexOf(System.String[], System.String, Int32, Int32)
   at DynamicClass.stub_System.Array_LastIndexOf(System.String[], System.String, Int32, Int32, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.Collections.Generic.List`1[System.String]_LastIndexOf(System.Collections.Generic.List`1<System.String>, System.String, Int32, Int32)
   at DynamicClass.stub_System.Collections.Generic.List`1[System.String]_LastIndexOf(System.Collections.Generic.List`1<System.String>, System.String, Int32, Int32, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.Collections.Generic.List`1[System.String]_LastIndexOf(System.Collections.Generic.List`1<System.String>, System.String)
   at DynamicClass.stub_virt_System.Collections.Generic.List`1[System.String]_LastIndexOf(System.Collections.Generic.List`1<System.String>, System.String, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.SR_InternalGetResourceString(System.String)
   at DynamicClass.stub_System.SR_InternalGetResourceString(System.String, System.RuntimeMethodHandle, System.RuntimeTypeHandle)
   at DynamicClass.dynamic_System.SR_GetResourceString(System.String)...

请问这是Pose库的固有限制,还是存在可行的解决办法?


解决方案

这是Pose库的线程隔离固有限制导致的问题。PoseContext.Isolate仅对当前执行线程生效,当在隔离上下文内启动新线程(比如Task.Run)时,新线程无法继承原线程的Shim配置,反而会触发Pose的方法重写逻辑进入无限循环,最终导致栈溢出。

可行的解决办法有三种:

1. 在新线程内重新创建隔离上下文

将目标方法调用放在新线程的PoseContext.Isolate中,确保Shim在新线程内生效:

PoseContext.Isolate(() =>
{
    _ = Task.Run(() =>
    {
        PoseContext.Isolate(() =>
        {
            Debug.WriteLine("In different task");
        }, consoleShim);
    });
}, consoleShim);

2. 缩小Shim的匹配范围

栈溢出的根源是Pose在处理新线程的系统方法时进入循环,可通过精确匹配目标方法而非泛型匹配,避免意外重写系统方法:

// 精确匹配Debug.WriteLine(string)方法
Shim consoleShim = Shim.Replace(() => Debug.WriteLine(It.IsAny<string>())).With(
    (string s) => Debug.WriteLine($"Hijacked: {s}"));

3. 同步等待任务完成(仅适用于允许同步的场景)

使用Wait()等待任务执行完毕,确保原线程的隔离上下文覆盖整个任务周期:

PoseContext.Isolate(() =>
{
    Task.Run(() =>
    {
        Debug.WriteLine("In different task");
    }).Wait();
}, consoleShim);

内容的提问来源于stack exchange,提问作者Matthew Conradie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:05:43