我有一個小的VC++應用程序,分爲兩部分。第一部分包含主要功能,並編譯爲靜態庫。第二部分是從第一部分鏈接到圖書館的Windows服務。從無關庫對象中腐蝕靜態變量(反之亦然)
我看到一些由內存損壞引起的奇怪行爲。通過設置數據斷點等,我可以確定每次從一個庫對象中的某些成員寫入兩個時,服務片中的靜態變量正在被破壞。相反,當靜態變量指向的位置被寫入時,庫對象的成員會被破壞。會不會有物體重疊?
編輯:我忘了提及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的初始化會影響_blah1Open和_blah2Open。 下面是一些存儲器地址以及大小。在運行時: &m_service:0x0053db84大小:4 &_blah1Open:0x0053db86大小:1 &_blah2Open:0x0053db85大小:1 &_blah1Handle:0x0053db83大小:2 &_blah2Handle:0x0053db81大小:2 正如你所看到的,_blah1Open和_blah2Open位於m_service的最後2個字節。 – Odrade 2010-04-27 15:38:08