【问题标题】:Access Read Violation thrown on EnterCriticalSection()EnterCriticalSection() 上引发的访问读取冲突
【发布时间】:2016-01-03 15:20:01
【问题描述】:

我正在开发一个使用临界区来同步实体数组的多线程应用程序。该数组保存在一个结构中,如下所示。 pe 数组的每个成员都包含自己的criticalSection,在访问该成员之前总是声明它(我已经全部检查过了)。

struct PlayerEntity {
    DWORD state;
    BOOL onScreen;
    DWORD team;

    DWORD_PTR baseAddr;
    BOOL valid;
    CRITICAL_SECTION critSec;
};

struct EntityList {
    DWORD count;
    PlayerEntity pe[128];
};

EntityList *getStaticEntityList() {
    static EntityList entityList;
    return &entityList;
}

在启动应用程序后,两个线程之一会在尝试进入临界区时看似随机地抛出异常(如下)。

Exception thrown at 0x00007FFC8813E7C5 (ntdll.dll) in RustExp.exe:
0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

我假设这个错误是由试图访问它们的 DebugInfo 对象的临界区对象引发的,因为每个对象的 DebugInfo 指针在初始化后都指向 0xffffffffffffffff。但是在错误检查之后,它们都指向 0xcdcdcdcdcdcdcdcd。

我试图查找有关关键部分对象及其成员的信息,但我似乎无法在它们上找到任何东西。所以我问,初始化的临界区对象是否应该将其 DebugInfo 指向 0xffffffffffffffff 以及临界区何时尝试访问其 DebugInfo(从而引发读取错误)?

注意:这是在 Windows 10 上运行的。

【问题讨论】:

  • 它位于winnt.h,类似于:typedef struct _RTL_CRITICAL_SECTION { PRTL_CRITICAL_SECTION_DEBUG DebugInfo; LONG LockCount; LONG RecursionCount; HANDLE OwningThread; HANDLE LockSemaphore; ULONG_PTR SpinCount; } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;。在winbase.h 中等同于CRITICAL_SECTION。但用户不应触摸任何字段。 InitializeCriticalSection()在使用前你用过吗?
  • 是的,它们都已初始化。在初始化之前,DebugInfo 指针为 NULL。之后它们都指向 0xffffffffffffffff。我还没有看到其他人描述这种行为,所以我认为这是问题所在。其他字段似乎都很好。
  • 是的,我没有想到这一点,但是看着我的代码,我有一个覆盖每个 PlayerEntity 的 critSec 的内存副本。直到我的两个线程在尝试访问同一个 PlayerEntity 时发生冲突时才抛出错误,这就是它随机发生的原因。感谢弗兰基的帮助。 PS:我现在如何结束这个问题?
  • 我发布了答案。你可以接受。

标签: c multithreading thread-safety access-violation critical-section


【解决方案1】:

我错误地取消了我的评论。但无论如何我做了检查,发现 DebugInfo 指针在临界区初始化期间被初始化为一个有效地址,该地址在所有测试(进入和离开该部分)期间保持不变。

如果您在关键部分初始化期间没有任何错误,则它应该被正确初始化,因此您不能在那里拥有0xFFFFFFFFFFFFFFFF

这仅导致一个结论,必须在代码中其他地方发生的内存损坏中搜索问题。

【讨论】:

    猜你喜欢
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多