|
Mike Nordell wrote:
I hope you'll never need it, but if you can't find the bug(s) you could limit the process to one CPU using SetProcessAffinityMask.
Must be a delayed echo...
Peace!
-=- James.
|
|
|
|
|
Somewhere you have some data that is being shared between two threads in your application. This memory is not being properly locked for access. Anytime you modify/read memory shared by multiple threads, you have to serialize access by some type of lock. (CRITICAL_SECTION works great)
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
would this result in crashes that seem to always result in an access violation in either the free() code ( it is deep in the MS heap allocator code) or new() ?
Tim Smith wrote:
Anytime you modify/read memory shared by multiple threads, you have to serialize access by some type of lock.
Yeah, I am doing this using mutexes there is a mutex for each list that I have (there are 3). Would CRITICAL_SECTION's be better ?
|
|
|
|
|
Generally, critical sections are better excluding 2 cases.
1. If the lock has to be shared between multiple processes.
2. If the lock is a long term lock where there will be a high occurrence of one thread having to wait for another thread to finish.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Jim Crafton wrote:
would this result in crashes that seem to always result in an access violation in either the free() code ( it is deep in the MS heap allocator code) or new() ?
IME, that is due to heap corruption, which is often caused by writing off the end of an allocated block of memory. Doing a double-free or a double-delete can also cause that problem.
Are multiple threads constantly allocating memory, passing the pointer(s) around, and then trying to free that memory? Misusing dynamically allocated memory is bad in the first place, but doing it in an MT application using the normal heap is a big no-no.
Peace!
-=- James.
|
|
|
|
|
Yes - if this is bad what are my options ?
Thanks !
|
|
|
|
|
Jim Crafton wrote:
Yes - if this is bad what are my options ?
If what is bad? Which portion of my message are you referring to? Options? Well, you can send your code to me (we will do an NDA beforehand, of course), and I will help you with it for the special reduced rate of US$125/hr! But barring that...
If you think that memory is being stepped on (or off of the end of) or otherwise mishanded, a debug build should quickly find that problem.
If a debug build is not an option, you may also be able to introduce code into the program to help track down where the problem is. For example, if your threads are allocating and deallocating proper objects (as opposed to simple types like char , int , double , etc.), you can do something like adding a bool member variable to the class that is set to true in the object's constructor and false in the destructor. If the destructor first tests to make sure that the member variable is true before setting it to false , you will be able to find a double-delete.
Adding "buffer variables" before and after the existing member variables can be used to detect memory overwrites. For example, make the buffer variables a set of 4 DWORD s, and place a set before and after the other member variables. In the constructor, fill the buffer variables with a known value (like 0x2468BEEF ). In the destructor, verify that the buffer variables all still equal the same value they were initialized to.
HTH
Peace!
-=- James.
|
|
|
|
|
Jim-
This is the kind of bug everyone dreads. But take heart, at least your crash is reproducable.
Do you know which line of code is failing ? You need MAP files and preferably have had Drwatson running when the program crashed.
Next time u get a chance, run DrWatson32 (from the winnt/system32 directory) and wait for the crash, then open the Drwtsn32.log file ( I forgot where this file is created, but u can search for it)
Check out http://support.microsoft.com/default.aspx?scid=kb;EN-US;q275481 for more detail
-
V
|
|
|
|
|
Hello,
I am using a STL multimap object to store keys and values.
The key are of type CPosition and values are of type CBirds*
class CPosition consists of two integers X and Y
class CPosition
{
public:
int X;
int Y;
};
To sort the keys I used something like:
struct lesscpos
{
bool operator () (const CPosition& Pos1, const CPosition& Pos2) const
{
if (Pos1.X < Pos2.X)
return true;
else if (Pos1.X > Pos2.Y)
return false;
else if (Pos1.Y < Pos2.Y)
return true;
else
return false;
}
};
I declare the multimap object like this:
multimap <CPostion, CBirds*, lesscpos> MyMap;
My program complies fine. The problem is when I use the count member function to determine how many values share the same key. It seems to me it is going into an infinite loop.
CPosition pos (i, j);
int x = MyMap.count (pos);
It hangs when it finds more than one value with the same key in the following function:
template<class _BidIt,
class _Diff> inline
void _Distance2(_BidIt _First, _BidIt _Last, _Diff& _Off,
bidirectional_iterator_tag)
{ // add to _Off distance between bidirectional iterators (redundant)
for (; _First != _Last; ++_First)
++_Off;
}
Can anyone help me with this one?
Thanks a lot
Best regards,
Alexandru Savescu
|
|
|
|
|
have you tried using map::lower_bound and map::upper_bound and then iterate through the results manually to see what is going on ?
also are i,j "valid" values ?
just guessing - don't know if this will help
|
|
|
|
|
I found my problem. It was the comparison function. It looks that it should strictly sort the keys, not just partially sort them.
It does not matter if i, j are invalid because in this case the count function will return 0 (that's what MSDN says).
Best regards,
Alexandru Savescu
|
|
|
|
|
Hi fellas
We have an application whose interface with the outside world is implemented as a collection of COM objects and typelibs. Please not that this is a fairly complex client-server application, which can set more than a thousand error conditions, in addition to the regular OS, Internet, COM, and SQL errors. These in-house error code are returned to the caller use HRESULT and SetErrorInfo, for clients other than those written in C++ can easily catch them.
This works very fine, with ASP and VB clients. But some conditions in the application could be simple warnings, instead of errors. What I would like to know is is there a way to return warnings (like S_FALSE, or any other non-error conditions) via HRESULT that will make VB catch the warning and get the human-readable message that goes along. This is quite easy to do with a C++ client, but how would I do it for a ASP or VB client to catch such warnings?
Any idea? Anybody done that before?
Michel
If I am wrong or said something stupid, I apologize in advance
|
|
|
|
|
I need to know how to write a Dird(r)iver function in Win32 code.
By Dird(r)iver i mean a function that takes a path name and gets all the filenames (and optionally folders) under that path including all the files in the subfolders (like the windows find program does).
Kuniva
--------------------------------------------
God gave man a penis and a brain but not enough blood to make both of 'em work at the same time.
|
|
|
|
|
A recursive function using FindFirstFile and co.
A tip: Append the found directory names and use FindFirstFile again using the the generated string for recursion. Don't try to SetCurrentDirectory to every dir found, it's dog slow.
|
|
|
|
|
Hi,
I need to set an event for my thread every 100 miliseond
automatcly -( after it's running i am doing ResetEvent and need to wait again for the event to happen) how can i do that ???
I am quiet sure that there is somthing for that and it would be a great help.
Thanks
|
|
|
|
|
If you are running on NT/W2K/XP/98/ME, you can use a waitable timer (CreateWaitableTimer).
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Hello Tim,
Thank you for your answer , I looked at this function and still didn't understand how to do that ( Set an Event automaticly every 100 milisecond),
I will appriciate if you can specify more or send me an example.
Bye
|
|
|
|
|
In my CFormView derived class my message map looks like (in .cpp):
BEGIN_MESSAGE_MAP(CMyFormView, CFormView)
ON_WM_ERASEBKGND()
ON_COMMAND(ID_PRINT_SELECTED,CFormView::OnFilePrint)
END_MESSAGE_MAP()
in my .h file i have:
afx_msg BOOL OnERASEBKGND(CDC* pDC); // also have tried virtual BOOL ...
and in my .cpp i have:
BOOL CMyFormView::OnERASEBKGND(CDC* pDC)
{
AfxMessageBox("erase");
return (TRUE);
}
why does my function for OnERASEBKGND never get called? i never get the messagebox.. any ideas?
obviously the point isn't to get a messagebox im just checkin to see if it ever gets called..
-dz
|
|
|
|
|
Seems you can only catch the WM_ERASEBKGND message in WindowProc of your CView.
snip:
LRESULT CMyView::WindowProc(UINT message, WPARAM wParam, LPARAM)
{
if ( message == WM_ERASEBKGND )
MessageBox("erase");
return CFormView::WindowProc(message, wParam, lParam);
}
|
|
|
|
|
that does work, i then have it call OnERASEBKGND(GetDC()), but it seems to call the erasing after the drawing.. as my background gets drawn over the data.. thanks for the help tho!
|
|
|
|
|
LRESULT CMyView::WindowProc(UINT message, WPARAM wParam, LPARAM)
{
if ( message == WM_ERASEBKGND )
{
MessageBox("erase");
return TRUE;
|
|
|
|
|
It's OnEraseBkgnd() not OnERASEBKGND().
Developers that like shiny objects also dig case mods and scratch-and-sniff stickers. Klaus Probst, The Lounge
|
|
|
|
|
thanks a bunch
-dz
|
|
|
|
|
The following code to populate a List Control Box with data from a database when a button is pressed works successfully when the List Control Box is placed on the main IDD_DIALOG. However when the List Control Box and button is placed on a tab, eg IDD_TAB1 the program hangs when the button is pressed.
(The header files "afxdb.h" and "odbcinst.h" are included in both the mainDlg.cpp and Tab1Dlg.cpp)
Any ideas as to why this is happening?
Any help is greatly appreciated.
Aoife
***********************************************************
void CInterfaceDlg::OnMainRead()
{
CDatabase database;
CString SqlString;
CString sNumber, sSender, sDate, sMessage;
CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile = "c:\\THE PROJECT\\Interface\\Project_Databases.mdb";
int iRec =0;
//Build ODBC connection string
sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s",sDriver,sFile);
TRY
{
//Open the Database
database.Open(NULL,false,false,sDsn);
//Allocte the Record set
CRecordset recset (&database);
//Build the SQL statement
SqlString = "SELECT Number, Sender, Date, Message "
"FROM pc_Inbox";
//Execute the query
recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
//Populate the Grids
ListView_SetExtendedListViewStyle(m_listControl,LVS_EX_GRIDLINES);
//Column width and heading
m_listControl.InsertColumn(0, "SMS No.", LVCFMT_LEFT, -1,0);
m_listControl.InsertColumn(1, "Sender", LVCFMT_LEFT, -1,1);
m_listControl.InsertColumn(2, "Date", LVCFMT_LEFT, -1,2);
m_listControl.InsertColumn(3, "Message", LVCFMT_LEFT, -1,3);
m_listControl.SetColumnWidth(0, 100);
m_listControl.SetColumnWidth(1, 100);
m_listControl.SetColumnWidth(2, 100);
m_listControl.SetColumnWidth(3, 200);
//Loop through each record
while (!recset.IsEOF())
{
//Copy each column into a variable
recset.GetFieldValue("Number",sNumber);
recset.GetFieldValue("Sender",sSender);
recset.GetFieldValue("Date",sDate);
recset.GetFieldValue("Message",sMessage);
//Insert values into the list control
iRec = m_listControl.InsertItem(0,sNumber,0);
m_listControl.SetItemText(0,1,sSender);
m_listControl.SetItemText(0,2,sDate);
m_listControl.SetItemText(0,3,sMessage);
//Go to the next record
recset.MoveNext();
}
//Close the Database
database.Close();
}
CATCH(CDBException, e)
{
//If a database exception occured, show an error message
AfxMessageBox("Database error: "+e->m_strError);
}
END_CATCH;
}
|
|
|
|
|
I try it. no problems!
maybe you should look:
1. use IsBOF before while ( oracle happen error when the recordset is empty)
2. sure Close Database at any condition
|
|
|
|
|