- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在调试 WinDbg 的一个问题,我可以始终如一地生成该问题。问题是当我用 WinDbg 运行可执行文件进行调试时,问题无法重现。可能是什么原因?
这是行为不同的代码:
CWnd* pWnd = GetDlgItem(IDOKCANCEL);
if(pWnd)
{
CString sOK;
sOK.LoadString(IDS_OK);
pWnd->SetWindowText(sOK);
}
这里,当我使用 WinDbg 运行时,按钮文本会正确更新,但当我正常运行时,它不会更新(这是错误)。
更新
正如我在评论中所说,问题不在于上面的代码,因为它甚至没有被调用。该操作在工作线程中完成,该工作线程将更新消息发送到此对话框。执行上述代码的最终消息永远不会发送,因此永远不会执行上述代码。
为什么工作线程不发送这条消息很有趣。打开数据库时,它会锁定在关键部分。 WinDbg 告诉我主线程是该关键部分的所有者,但我无法从调用堆栈或任何其他方式看到它未能解锁关键部分的位置。
使问题复杂化的是,如果我使用调试器运行它,它工作正常。我添加了日志输出,但它也开始与此更改一起正常工作。
我可以用调试器捕获它的唯一方法是在正常模式下运行它,产生问题,然后附加调试器,它显示它已锁定在关键部分。它显示主线程是该关键部分的所有者,但不清楚为什么它处于锁定状态。关键部分只是在一个函数中被锁定和解锁,并且它在外面。
更新 2
我只在整个项目的一个文件中使用关键部分,并且只有两个函数(当它打开数据库和记录集时)。
BOOL CADODatabase::Open(LPCTSTR lpstrConnection, LPCTSTR lpstrUserID, LPCTSTR lpstrPassword)
{
CString database = GetSourceDatabase( lpstrConnection, NULL );
// get the appropriate critical section based on database
g_dbCriticalSection = GetDbCriticalSection( database );
if( g_dbCriticalSection)
g_dbCriticalSection->Lock();
HRESULT hr = S_OK;
if(IsOpen())
Close();
if(wcscmp(lpstrConnection, _T("")) != 0)
m_strConnection = lpstrConnection;
ASSERT(!m_strConnection.IsEmpty());
try
{
if(m_nConnectionTimeout != 0)
m_pConnection->PutConnectionTimeout(m_nConnectionTimeout);
hr = m_pConnection->Open(_bstr_t(m_strConnection), _bstr_t(lpstrUserID), _bstr_t(lpstrPassword), NULL);
if( g_dbCriticalSection)
g_dbCriticalSection->Unlock();
return hr == S_OK;
}
catch(_com_error &e)
{
dump_com_error(e);
if( g_dbCriticalSection)
g_dbCriticalSection->Unlock();
return FALSE;
}
}
第二个函数还有其他明显的缺陷,但请忽略它,它是遗留代码。
BOOL CADORecordset::Open(_ConnectionPtr mpdb, LPCTSTR lpstrExec, int nOption)
{
BSTR bstrConnString;
m_pConnection->get_ConnectionString(&bstrConnString);
CString database = GetSourceDatabase( bstrConnString, m_pConnection );
g_dbCriticalSection = GetDbCriticalSection( database );
if( g_dbCriticalSection)
g_dbCriticalSection->Lock();
Close();
if(wcscmp(lpstrExec, _T("")) != 0)
m_strQuery = lpstrExec;
ASSERT(!m_strQuery.IsEmpty());
if(m_pConnection == NULL)
m_pConnection = mpdb;
m_strQuery.TrimLeft();
BOOL bIsSelect = m_strQuery.Mid(0, _tcslen(_T("Select "))).CompareNoCase(_T("select ")) == 0 && nOption == openUnknown;
int maxRetries = 10;
bool bContinue = true;
CursorTypeEnum adCursorType = adOpenStatic;
if (!m_bSQLEngine)
{
// MDB Engine
adCursorType = adOpenStatic;
m_pConnection->CursorLocation = adUseClient;
}
else
{
// SQL Engine
adCursorType = adOpenDynamic;
m_pConnection->CursorLocation = adUseServer;
}
int currentCommandTimeout = m_pConnection->CommandTimeout;
if( g_dbCriticalSection)
g_dbCriticalSection->Unlock();
for (int iRetry = 0; (iRetry < maxRetries) && bContinue; iRetry++)
{
try
{
// we just use an auto lock object so it is unlocked automatically, it uses same
// critical section object.
if( g_dbCriticalSection)
g_dbCriticalSection->Lock();
int newCommandTimeout = currentCommandTimeout + 15 * iRetry;
m_pConnection->CommandTimeout = newCommandTimeout;
if(bIsSelect || nOption == openQuery || nOption == openUnknown)
{
m_pRecordset->Open((LPCTSTR)m_strQuery, _variant_t((IDispatch*)mpdb, TRUE),
adCursorType, adLockOptimistic, adCmdUnknown);
}
else if(nOption == openTable)
{
m_pRecordset->Open((LPCTSTR)m_strQuery, _variant_t((IDispatch*)mpdb, TRUE),
adOpenDynamic, adLockOptimistic, adCmdTable);
}
else if(nOption == openStoredProc)
{
m_pCmd->ActiveConnection = mpdb;
m_pCmd->CommandText = _bstr_t(m_strQuery);
m_pCmd->CommandType = adCmdStoredProc;
m_pRecordset = m_pCmd->Execute(NULL, NULL, adCmdText);
}
else
{
TRACE( _T("Unknown parameter. %d"), nOption);
if( g_dbCriticalSection)
g_dbCriticalSection->Unlock();
return FALSE;
}
if( g_dbCriticalSection)
g_dbCriticalSection->Unlock();
bContinue = false;
}
catch(_com_error &e)
{
if( g_dbCriticalSection)
g_dbCriticalSection->Unlock();
dump_com_error_without_exception(e, _T("Open"));
// retry Query timeout
CString szDescription;
_bstr_t bstrDescription(e.Description());
szDescription.Format( _T("%s"), (LPCTSTR)bstrDescription);
if ((szDescription.Find(_T("Query timeout expired")) == -1) || (iRetry == maxRetries - 1))
{
m_pConnection->CommandTimeout = currentCommandTimeout;
throw CADOException(e.Error(), e.Description());
}
Sleep (1000);
bContinue = true;
}
}
m_pConnection->CommandTimeout = currentCommandTimeout;
return m_pRecordset != NULL && m_pRecordset->GetState()!= adStateClosed;
}
为了完整起见,上面调用了这个函数:
static CCriticalSection* GetDbCriticalSection(const CString& database)
{
// For now we only care about one database and its corresponding critical section
if (database.CompareNoCase( _T("Alr") ) == 0)
return &g_csAlrDb; // g_csAlrDb is defined static global in this file
else
return 0;
}
Open() 函数被各种数据库调用,我只锁定保护对一个数据库的访问。正如您所看到的,有相应的锁定/解锁,因此不确定这些函数的代码如何使关键部分处于锁定状态。难道是因为MFC issue ?
最佳答案
就我而言,大多数情况下,当 C++ 软件在调试版本和发布版本之间表现不同时,这是因为未初始化的变量、链接的不同库或编译器优化适得其反。
要跟踪错误,请尝试评估变量和函数返回值,即 LoadString
,例如使用 AfxMessageBox()
。
关于c++ - 代码在 WinDbg 上运行良好,但没有它就很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44790735/
嗨,我正在考虑开发一种文件传输程序,想知道我是否想要尽可能好的加密,我应该使用什么? 我会用 C# 开发它,所以我可以访问 .net 库 :P在我的 usb 上有一个证书来访问服务器是没有问题的,如果
我创建的这个计算两个数组的交集是线性的方法的复杂度(在良好、平均、最差的情况下)? O(n) public void getInt(int[] a,int[] b){ int i=0; int
我已经能够使用 RTCPeerConnection.getStats() API 获得 WebRTC 音频调用的各种统计信息(抖动、RTT、丢包等)。 我需要将整体通话质量评为优秀、良好、一般或差。
基本问题: 如果我正在讲述/修改数据,我应该通过索引硬编码索引访问文件的元素,即 targetFile.getElement(5);通过硬编码标识符(内部翻译成索引),即 target.getElem
在 Linux 上,我想知道要调用什么“C”API 来获取每个 CPU 的统计信息。 我知道并且可以从我的应用程序中读取 /proc/loadavg,但这是系统范围的负载平均值,而不是每个 CPU 的
在客户端浏览器中使用 fetch api,GET 或 POST 没有问题,但 fetch 和 DELETE 有问题。它似乎将 DELETE 请求方法更改为 OPTIONS。 大多数研究表明是一个cor
我是一名优秀的程序员,十分优秀!