我有一个小型的vc++应用程序,分为两部分。第一部分包含主要功能,并编译为静态库。第二部分是windows服务,它从第一部分链接到库。
我看到一些奇怪的行为是由记忆衰退引起的。通过设置数据断点等,我能够确定每次写入两个库对象中的某个成员时,服务条中的静态变量都会被损坏。相反,当写入静态变量指向的位置时,库对象的成员会损坏。有物体重叠吗?
编辑:我忘了在我的服务代码中提到blahhelper实例在全局范围内。这支持重叠理论,因为blahhelper和servicebase::m_服务都应该在exe的全局数据区域中。
edit2:通过查看原始内存并检查所有相关对象的地址,我已经确认blahhelper对象与servicebase::m_服务指针重叠。为什么会这样?
下面是感兴趣的类定义:
// 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;
};
这是图书馆里的一个班。当我将库链接到我的service 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_服务。作为进一步的确认,我注释掉了blahhelper实现中写入这些值的每一行代码,这些错误就消失了。
如果我改变了blahhelper成员的声明顺序,我仍然会看到内存损坏问题,但症状会改变。
如果我直接将库代码包含在服务中,我就不会再看到这个问题了。除了诊断目的,我不能这样做,但它确实表明在链接过程中发生了一些奇怪的事情。
另一件需要注意的事情是,库是用多字节字符集编译的,而链接库的服务应用程序是用unicode编译的。这将很难改变。
有谁能提出可能发生这种情况的可能原因,或诊断问题的方法?当我意识到我有内存损坏,我希望有一个简单的原因(如缓冲区溢出)。但是,我不知道为什么一个物体会像这样踩在另一个物体上。