跟踪静态构造函数的执行

发布于 2024-10-15 12:02:52 字数 343 浏览 4 评论 0原文

我在这里遇到一个问题,其中一个类的静态构造函数在应该调用之前被调用。 (即,DI/IoC 未设置,并且它从服务定位器返回 null/异常)。

不幸的是,我对静态构造函数没有太多控制权,不要问我为什么它依赖于 DI/IoC 来设置,但确实如此。

在我的应用程序中,在我的 IoC 准备就绪之前,不应引用此类静态或其他任何内容,但静态构造函数无论如何都会执行。

有没有一种简单的方法来确定哪一行导致构造函数执行? 注意:我无法在静态构造函数中设置断点,因为这一切都发生在 ASP.NET 远程调试器可以附加到 Web 服务器(在 Global.asax.cs 中)之前

I'm running into a problem here where a static constructor of one of my classes is being called before it should be. (I.e, DI/IoC isn't set up and it's getting null/exceptions back from the service locator).

I unfortunately don't have a lot of control over the static constructor, don't ask me why it's relying on DI/IoC to be set up, but it is.

In my app, nothing should be referencing this class static or otherwise before my IoC is ready to go, but the static constructor is executing anyway.

Is there an easy way to determine what line caused the constructor to execute? Note: I cannot breakpoint in the static constructor because this is all happening before the remote debugger for ASP.NET can attach to the web server (in Global.asax.cs)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无所的.畏惧 2024-10-22 12:02:53

您无法控制静态构造函数何时执行。
将您正在执行的任何操作从构造函数移至静态 Initialize() 函数。
当你准备好时就打电话给那个人。
不依赖于静态构造函数何时执行。

检查此链接

静态构造函数具有以下内容

<块引用>

属性:

调用静态构造函数
自动初始化类
在创建第一个实例之前
或引用任何静态成员。

无法调用静态构造函数
直接。

用户无法控制何时
静态构造函数在
程序。

You have no control as to when the static constructor is executed.
Move whatever you are doing from your constructor to a static Initialize() function.
Call that one whenever you are ready.
Do not depend on when the static constructor is executed.

Check this link

Static constructors have the following

properties:

A static constructor is called
automatically to initialize the class
before the first instance is created
or any static members are referenced.

A static constructor cannot be called
directly.

The user has no control on when the
static constructor is executed in the
program.

感受沵的脚步 2024-10-22 12:02:53

也许您应该跳过使用静态构造函数?是必然的吗?

public class SomeClass
{
    private static bool IsInizialized = false;

    public SomeClass()
    {
        if (!IsInizialized)
        {
            // static constuctor thread safe but this doesn't
            //
            lock (this)
            {
                if (!IsInizialized)
                {
                    IsInizialized = true;
                    // all what static constructor does
                }
            }
        }
    }
}

Maybe you should skip using static constructor? Is it necessarily?

public class SomeClass
{
    private static bool IsInizialized = false;

    public SomeClass()
    {
        if (!IsInizialized)
        {
            // static constuctor thread safe but this doesn't
            //
            lock (this)
            {
                if (!IsInizialized)
                {
                    IsInizialized = true;
                    // all what static constructor does
                }
            }
        }
    }
}
感悟人生的甜 2024-10-22 12:02:52

一如既往,使用:

Debugger.Break()

As always, use:

Debugger.Break()
凉墨 2024-10-22 12:02:52

这可以使用 Windbg 和 sosex 来完成。这是示例代码

using System;
namespace Code
{
class Test
{
  public static int i;
  static Test()
  {
    i = 10;
    Console.WriteLine(i);
  }
  static void Main()
  {
    Console.WriteLine(Test.i);
    Console.Read();
  }
}
}

以下是步骤

  1. 将进程附加到 Windbg
  2. 使用 .load sosex 加载 sosex
  3. 接下来发出命令 !mbm
    *Code.Test..cctor*
  4. 调试器在调用时中断
    静态构造函数,之后您可以发出 !mk 来获取
    callstack

!mk 的输出

0:000> !mk
Thread 0:
     ESP              EIP
00:M 000000000026def8 000007ff00150120 Code.Test..cctor()(+0x0 IL)(+0x0 Native)
01:U 000000000026df00 000007fef43a10b4 clr!CallDescrWorker+0x84
02:U 000000000026df40 000007fef43a11c9 clr!CallDescrWorkerWithHandler+0xa9
03:U 000000000026dfc0 000007fef43a32b4 clr!DispatchCallDebuggerWrapper+0x74
04:U 000000000026e060 000007fef43aafdf clr!MethodTable::RunClassInitEx+0x1ff
05:U 000000000026e1b0 000007fef43aaca8 clr!MethodTable::DoRunClassInitThrowing+0x55e
06:U 000000000026ec70 000007fef43a3470 clr!MethodTable::CheckRunClassInitThrowing+0xe3
07:U 000000000026eca0 000007fef44cb848 clr!MethodDesc::DoPrestub+0x587
08:U 000000000026edb0 000007fef43a23f3 clr!PreStubWorker+0x1df
09:U 000000000026ee70 000007fef4362d07 clr!ThePreStubAMD64+0x87
0a:U 000000000026ef40 000007fef43a10b4 clr!CallDescrWorker+0x84
0b:U 000000000026ef80 000007fef43a11c9 clr!CallDescrWorkerWithHandler+0xa9
0c:U 000000000026f000 000007fef43a1245 clr!MethodDesc::CallDescr+0x2a1
0d:U 000000000026f230 000007fef44a1675 clr!ClassLoader::RunMain+0x228
0e:U 000000000026f480 000007fef44a17ac clr!Assembly::ExecuteMainMethod+0xac
0f:U 000000000026f730 000007fef44a1562 clr!SystemDomain::ExecuteMainMethod+0x452
10:U 000000000026fce0 000007fef44a3dd6 clr!ExecuteEXE+0x43
11:U 000000000026fd40 000007fef44a3cf3 clr!CorExeMainInternal+0xc4
12:U 000000000026fdb0 000007fef4527365 clr!CorExeMain+0x15
13:U 000000000026fdf0 000007fef6883309 mscoreei!CorExeMain+0x41
14:U 000000000026fe20 000007fef6915b21 MSCOREE!CorExeMain_Exported+0x57
15:U 000000000026fe50 0000000077a6f56d KERNEL32!BaseThreadInitThunk+0xd
16:U 000000000026fe80 0000000077ba3021 ntdll!RtlUserThreadStart+0x1d

这是上述示例HTH

This could be done using Windbg and sosex. Here is the sample code

using System;
namespace Code
{
class Test
{
  public static int i;
  static Test()
  {
    i = 10;
    Console.WriteLine(i);
  }
  static void Main()
  {
    Console.WriteLine(Test.i);
    Console.Read();
  }
}
}

And here are the steps

  1. Attach the process to windbg
  2. Load sosex using .load sosex
  3. Next issue the command !mbm
    *Code.Test..cctor*
  4. The debugger breaks on call to the
    static constructor after which you could issue !mk to get the
    callstack

Here is the output from !mk for the above sample

0:000> !mk
Thread 0:
     ESP              EIP
00:M 000000000026def8 000007ff00150120 Code.Test..cctor()(+0x0 IL)(+0x0 Native)
01:U 000000000026df00 000007fef43a10b4 clr!CallDescrWorker+0x84
02:U 000000000026df40 000007fef43a11c9 clr!CallDescrWorkerWithHandler+0xa9
03:U 000000000026dfc0 000007fef43a32b4 clr!DispatchCallDebuggerWrapper+0x74
04:U 000000000026e060 000007fef43aafdf clr!MethodTable::RunClassInitEx+0x1ff
05:U 000000000026e1b0 000007fef43aaca8 clr!MethodTable::DoRunClassInitThrowing+0x55e
06:U 000000000026ec70 000007fef43a3470 clr!MethodTable::CheckRunClassInitThrowing+0xe3
07:U 000000000026eca0 000007fef44cb848 clr!MethodDesc::DoPrestub+0x587
08:U 000000000026edb0 000007fef43a23f3 clr!PreStubWorker+0x1df
09:U 000000000026ee70 000007fef4362d07 clr!ThePreStubAMD64+0x87
0a:U 000000000026ef40 000007fef43a10b4 clr!CallDescrWorker+0x84
0b:U 000000000026ef80 000007fef43a11c9 clr!CallDescrWorkerWithHandler+0xa9
0c:U 000000000026f000 000007fef43a1245 clr!MethodDesc::CallDescr+0x2a1
0d:U 000000000026f230 000007fef44a1675 clr!ClassLoader::RunMain+0x228
0e:U 000000000026f480 000007fef44a17ac clr!Assembly::ExecuteMainMethod+0xac
0f:U 000000000026f730 000007fef44a1562 clr!SystemDomain::ExecuteMainMethod+0x452
10:U 000000000026fce0 000007fef44a3dd6 clr!ExecuteEXE+0x43
11:U 000000000026fd40 000007fef44a3cf3 clr!CorExeMainInternal+0xc4
12:U 000000000026fdb0 000007fef4527365 clr!CorExeMain+0x15
13:U 000000000026fdf0 000007fef6883309 mscoreei!CorExeMain+0x41
14:U 000000000026fe20 000007fef6915b21 MSCOREE!CorExeMain_Exported+0x57
15:U 000000000026fe50 0000000077a6f56d KERNEL32!BaseThreadInitThunk+0xd
16:U 000000000026fe80 0000000077ba3021 ntdll!RtlUserThreadStart+0x1d

HTH

も让我眼熟你 2024-10-22 12:02:52

下面是我的静态构造函数调试经验,

当我尝试通过在静态字段引用的行上放置断点进行调试时,我没有获得对静态构造函数的调试控制。

我在静态构造函数入口处保留了断点,并从静态字段引用的行中删除了断点。现在调试控制开始进入静态构造函数代码。

此图显示了带有断点的编辑器的外观

Below is my static constructor debugging experience,

When I was trying to debug by placing a breakpoint on the line where the static field had referenced, I was not getting debug control on the static constructor.

I kept breakpoint on the static constructor entrance, removed the breakpoint from the line where the static field had referenced. Now Debug control started coming into the static constructor code.

This image shows how your editor with breakpoints would look like

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文