gpt4 book ai didi

c++ - 来自无关库对象的静态变量损坏(反之亦然)

转载 作者:行者123 更新时间:2023-11-28 08:29:43 31 4
gpt4 key购买 nike

我有一个小型 VC++ 应用程序,分成两部分。第一部分包含主要功能并被编译为静态库。第二部分是从第一部分链接到库的 Windows 服务。

我看到一些由内存损坏引起的奇怪行为。通过设置数据断点等,每次将库对象之一的某些成员写入两个时,我能够确定服务 block 中的静态变量被破坏。相反,当静态变量指向的位置被写入时,库对象的成员被破坏。会不会有对象重叠?

编辑:我忘了在我的服务代码中提到 BlahHelper 的实例在全局范围内。这支持重叠理论,因为 BlahHelper 和 ServiceBase::m_service 应该都在 exe 的全局数据区域中。

EDIT2:通过查看原始内存并检查所有相关对象的地址,我确认 BlahHelper 对象与 ServiceBase::m_service 指针重叠。为什么会这样?

下面是感兴趣的类定义:

// This is the basis of my service.  I derive from this and override 
// the start() and stop() methods to implement the service.
class ServiceBase
{
public:

virtual ~ServiceBase();

static void Run(ServiceBase& service);

protected:

ServiceBase(DWORD controlsAccepted = SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN);

virtual void Start(DWORD control) = 0;
virtual void Stop(DWORD control) = 0;

void UpdateState(DWORD state,
HRESULT errorCode = S_OK);

const std::wstring& ServiceName() const;

private:

void SetServiceStatus();

static void WINAPI ServiceMain(DWORD argumentCount,
PWSTR* arguments);

static void WINAPI Handler(DWORD control);

static ServiceBase* m_service; // This is being corrupted
SERVICE_STATUS_HANDLE m_handle;
ServiceStatus m_status;
std::wstring m_serviceName;

};

这是库中的一个类。当我将库链接到我的服务 exe 并实例化一个 BlahHelper 对象时,我看到一些奇怪的内存损坏问题。

// Writing to _blah2Open or _blah1Open causes corruption of ServiceBase::m_status
class BlahHelper
{
// Names changed to protect the innocent
public:
BlahHelper();
~BlahHelper();

HRESULT GetSomeInfo();
HRESULT GetSomeStatus(LPWORD statPosition);

void Init(char blah1Sp[], char blah2Sp[], HWND messageWindow);
bool Blah1ConnectionOpen(){return _blah2Open;};
bool Blah2ConnectionOpen(){return _blah1Open;};
hash_map<string,short> GetSomeJunk(){return _someJunk;};
void Refreshblah1Config();
bool HasItemsTakenSensor(){return _blah1HasItemsTakenSensor;};
void Enterblah2();
void blah2Exited();
void Ackblah2ExitReq();
void Cleanup();
void Initblah1();
void Initblah2();

private:

LPWFSRESULT OpenSession(char* spName, HSERVICE* handle);
LPWFSRESULT Getblah1Caps();
void Cleanupblah1();
void Cleanupblah2();
void Closeblah1();
void Closeblah2();
void Openblah1();
void Openblah2();
void Registerblah1();
void Registerblah2();
void Checkblah1Caps();
void CheckSomeJunk();
void Getblah1Config();
void LogMessage(string message, int logLevel);

char* _SpName1;
char* _SpName2;
HWND _messageWindow;
HSERVICE _Handle1;
HSERVICE _Handle2;
bool _blah2Open; // writing to this causes corruption of ServiceBase::m_service
bool _blah1Open; // writing to this causes corruption of ServiceBase::m_service
const string _logSource;
const int _logMsgId;
bool _blah1HasItemsTakenSensor;

hash_map<string, short> _someJunk;
};

正如我所说,数据断点显示写入 _blah1Open 或 _blah2Open 会损坏 ServiceBase::m_service。作为进一步确认,我注释掉了写入这些值的 BlahHelper 实现的每一行,并且损坏消失了。

如果我更改 BlahHelper 成员的声明顺序,我仍然会看到内存损坏问题,但症状会发生变化。

如果我直接在服务中包含库代码,我就不会再看到这个问题了。除了诊断目的,我不能这样做,但它确实表明链接过程中发生了一些奇怪的事情。

另一件需要注意的事情是,该库是使用 Muli-Byte 字符集编译的,而链接该库的服务应用程序是使用 Unicode 编译的。这将很难改变。

谁能提出发生这种情况的可能原因,或诊断问题的方法?当我意识到我有内存损坏时,我希望有一个简单的原因(比如缓冲区溢出)。但是,我不知道为什么一个物体会像这样踩到另一个物体。

最佳答案

你是说m_service本身变了还是*m_service变了?

如果您检查 &_blah2Open 和 m_service 地址匹配吗?

(记住_blah2Open是一个变量,m_service是一个指针,所以你需要_blah2Open的地址和m_service的值)

_blah2Open 的地址必然位于堆或栈上,作为 CBlahHelper 的一部分进行分配,因此该地址不太可能指向 m_service 的内容。

如果是m_service指向的内容改变的情况,一种可能的情况是:m_service 在代码中的某处进行了初始化,但由于某种原因在您的情况下未调用静态初始化程序,因此 m_service 随机指向某处并且当某些对象分配到那里时内容被覆盖。您需要在程序运行的最开始放置一个数据断点,并跟踪每次 m_service 何时更改。

另一方面,如果您说 m_service 和 _blah1Open 在故障点具有相同的地址:两个不同的变量(不在一个 union 中)总是有不同的地址,所以 m_service 和 _blah2Open 在内存中共享同一个地址是不合乎逻辑的。这意味着编译器生成的代码出现根本性故障的可能性极小......

关于c++ - 来自无关库对象的静态变量损坏(反之亦然),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2722008/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com