|
Joaquín M López Muñoz wrote:
You can safely avoid memory leaks if you spawn the thread in a separate process
Does this mean another executable? If not how do I spawn another process inside my console app? If you have an example I would greatly appreciate it..
Thanks,
Rob
|
|
|
|
|
This is only intended as a last resort, if you cannot modify the code for the worker thread. Since you seemingly can, I'd suggest you try and convert the thread into responsive code: you can avoid locking by specifying INTERNET_FLAG_ASYNC in the construction of your CInternetSession object.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello,
INTRODUCTION:
1. I have a dialog that is used to monitor the backup of some files.
2. This dialog has a thread that makes the backup (in order to avoid the hung effect that creates not repainting the window...).
3. My problems appear when while I'm saving data to the floppy disk I remove it: when this happens an exception gets fired.
QUESTION:
I wanted to handle that in order to prevent my app to get hung if a user does this.
The strange fact is that after reading a little of Jeff Richter's book (advanced programming in windows) I've thought that I had understood how the SEH worked, but now this message is appearing and I don't understand why.
this is my code:
__try
{
iRet = CopyFile(csFullSourcePath, csFullDestinationPath, FALSE);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
iRet = 0;
}
if (iRet == 0)
{
iNumErrorsFound++;
csAuxiliar += " : ERROR FOUND!";
bErrorFound = true;
}
the thread has some CString, HANDLE, DWORD and WORD variables...
and the error messages that I receive are:
nonstandard extension used: 'ThreadRespatllar' uses SEH and 'csFullSourcePath' has destructor
where 'ThreadRespatllar' is the thread name and 'csFullSourcePath' is one of the CString variables that are declared in the thread.
NOTE: I get one warning message for each CString declared in the thread.
Thank you in advance.
|
|
|
|
|
This is just a guess, but possibly mixing SEH with MFC exception handling in a MT environment is the culprit. Just wondering though, are these error messages you get when compiling, linking, or executing?
Chirs Meech
"what makes CP different is the people and sense of community, things people will only discover if they join up and join in." Christian Graus Nov 14, 2002.
"AAAAAAAAAHHHHHH!!!!! Those leaks are driving me crazy! How does one finds a memory leak in a garbage collected environment ??! Daniel Turini Nov. 2, 2002.
|
|
|
|
|
Those errors appear at compilation time.
Thank you for your interest.
|
|
|
|
|
Chris Meech wrote:
This is just a guess, but possibly mixing SEH with MFC exception handling in a MT environment is the culprit
Actually, MT has nothing to do with it. SEH and C++ EH is inherently incompatible - you simply can't have C++ stack unwinding in a function that uses SEH (among other things because MS C++ EH is implemented in terms of SEH).
If one absolutely needs both, one would have to create separate functions, where one uses one kind of EH, and then calls the other function that uses the other kind of EH.
|
|
|
|
|
You can handle regular C++ exceptions and SEH all in one with a little code like this:
class SEH_exception:public std::runtime_error
{
public:
SEH_exception(unsigned int code,const char* msg):std::runtime_error(msg),code_(code){}
unsigned int code()const{return code_;}
private:
unsigned int code_;
};
static void SEH_translator(unsigned int code,EXCEPTION_POINTERS*)
{
std::string msg;
switch(code){
case EXCEPTION_ACCESS_VIOLATION: msg="access violation";break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: msg="array bounds exceeded";break;
case EXCEPTION_BREAKPOINT: msg="breakpoint exception";break;
case EXCEPTION_DATATYPE_MISALIGNMENT: msg="datatype misalignment";break;
case EXCEPTION_FLT_DENORMAL_OPERAND: msg="flt denormal operand";break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: msg="flt divide by zero";break;
case EXCEPTION_FLT_INEXACT_RESULT: msg="flt inexact result";break;
case EXCEPTION_FLT_INVALID_OPERATION: msg="flt invalid operation";break;
case EXCEPTION_FLT_OVERFLOW: msg="flt overflow";break;
case EXCEPTION_FLT_STACK_CHECK: msg="flt stack check";break;
case EXCEPTION_FLT_UNDERFLOW: msg="flt underflow";break;
case EXCEPTION_ILLEGAL_INSTRUCTION: msg="illegal instruction";
case EXCEPTION_IN_PAGE_ERROR: msg="in page error";break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: msg="divide by zero";break;
case EXCEPTION_INT_OVERFLOW: msg="overflow"; break;
case EXCEPTION_INVALID_DISPOSITION: msg="invalid disposition";break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION: msg="noncontinuable exception";break;
case EXCEPTION_PRIV_INSTRUCTION: msg="priv instruction";break;
case EXCEPTION_SINGLE_STEP: msg="single step trap";break;
case EXCEPTION_STACK_OVERFLOW: msg="stack overflow";break;
default:{
char buf[1024];
sprintf(buf,"SEH exception (%x)",code);
msg=buf;
}
break;
}
throw SEH_exception(code,msg.c_str());
}
_set_se_translator(SEH_translator); Now use C++ good old try and catch (no leading underscores). Good luck.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello,
Excuse me for having not said anything till now, I've been out of my office some days...
I've tried it, but the compiler tells me:
error C2653: 'std' : is not a class or namespace name Also I've tried to write down (just before the class definition)
using namespace std; but then the message is:
error C2871: 'std' : does not exist or is not a namespace Moreover, after all of this has been done I've tried to get it work using the normal try/catch exception handlers, but if I place them there it seems that the thread gets locked somewhere/somehow...
the code that I've used is:
try
{
hArxiuLog = CreateFile (csFullPathArxiuRegistreCS,GENERIC_WRITE,FILE_SHARE_WRITE | FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
}
catch(CException *e)
{
hArxiuLog = INVALID_HANDLE_VALUE;
e->Delete();
}
<code> What I've understood (reading to the MSDN) is that if I place a try statement the exceptions that are in the catch clause are handled by the contents of the catch clause. Then, the code that I've implemented should catch all the exceptions (I think that all the CExceptions are derived from CException class) and then as I delete the exception e->Delete() the code should continue executing normally after the catch clause without hanging the thread.
Am I right?
Thank you in advance.
|
|
|
|
|
As for the std problem, include the definition of std:runtime_error with
#include <stdexcept> Now, replace
catch(CException *e) with
catch(std::exception& e) and don't delete anything. If you like the MFC exceptions more, change the definition of SEH_exception to derive from CException instead of std:runtime_error .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
This has been the fastest answer that I've received!
I'll try it now, thank you very much...
|
|
|
|
|
Hello,
OK, as it was expected, your code works.
Now I don't get errors at compilation time and the thread doesn't hangs.
The only problem is that I cannot avoid the system messages to appear, is there any way to do it?
Under XP Professional it even appears a icon in the system tray...
Thank you in advance.
|
|
|
|
|
What system messages?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello again,
the system messages that appear seems to be the same ones that appeared before placing the SEH handling...
The typical There's no disk in drive A...
There's an error in the delayed writting...
with the CANCEL, RETRY... options...
It seems that the exception is not being catched...
Here's a litle sample of the handling routine...
try
{
iRetornOperacioCopia = CopyFile(csFullPathOrigenPrograma, csFullPathDestiPrograma, FALSE);
}
catch(std::exception& e)
{
iRetornOperacioCopia = 0;
} Thank you in advance...
|
|
|
|
|
Well, maybe SetErrorMode can be of help in supressing system error messages.
It seems that the exception is not being catched...
Didn't you say in your previous post it was working?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello again...
Sorry I've been interrupted during the test and what I've been only capable to see is that the thread was not getting hung.
Althought the thread is not getting hung I've placed some breakpoints inside the catch statement and the program flow never goes through them...
It is strange... I've taken a look at the MSDN and all the exceptions that can happen are the ones that you haev in your list... but the catch is not getting them...
Thank you in advance...
PS: I don't want to bother you with too much questions... please feel free to stop answering me when you consider that that's enough...
|
|
|
|
|
OK, now I think I know what your problem is. Those system message boxes saying things like "No diskette in drive A:" are what you want to supress, right? If so, then exceptions (SEH or the other) have nothing to do with the issue. The following sample shows how to supress the message box in a CopyFile opreation, the function merely returning FALSE as the result:
int main(void)
{
UINT error_mode=::SetErrorMode(0);
::SetErrorMode(error_mode|SEM_FAILCRITICALERRORS);
BOOL b=::CopyFile("A:\\pepe","C:\\pepe",FALSE);
return 0;
} Hope this helps.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello again...
Yes, it should have worked...
I've remembered that I tried this before when I've seen a variable declared at the beggining of the thread (UINT uiErrorModeANT = 0; ) that was the one that I had used in order to set the new error mode and at the last point of the thread flow I used it to return the error state at it's original state.
Some time ago I decided to left that function without that security because of I had not enough time...
- I had tried to use the try/catch and it didn't worked because it hung the thread (I suppose that it was because I didn't know how to make it work).
- I had tried setting the error mode to "0 | SEM_FAILCRITICALERRORS" too and it didn't worked too.
- Now I was wondering about SEH, and after your help, I've seen that the exception raised wasn't captured by the SEH...
I don't know what more to search or to do... but I must solve that because is a weak point of my program and it can make possible to enter to the OS without permission.
And I would like to leave the messages that appear when I take the floppy out from the drive, but then the taskbar appears only for a while, but it give access to it to the user; this is a very big problem for me because I write apps that must start at the beggining and end shutting down the PC...
NOTE:
It seems that the rightest approach was the try/catch, at least it blocked the message, the only problem is that I don't know why it blocked the thread too...
Can I send you the thread code? (it's a small function)...
Thank you in advance...
PS: Before sending you the code I'll wait for your answer... meanwhile I'll continue trying to solve it.
|
|
|
|
|
Hello again,
I'll finish meeting you at your office...
That's working now...
The changes have been:
try
{
iRetornOperacioCopia = CopyFile(csFullPathOrigenPrograma, csFullPathDestiPrograma, FALSE);
}
catch(...)
{
iRetornOperacioCopia = 0;
}
and I suppose that the program flow should be:
1. The program tries to make the copy...
2. The program fails copying because there's no disk.
3. The program enters into the catch clause and assigns 0 to iRetornOperacioCopia.
4. The program flow continues outside the catch clause.
What has surprised me is:
1. Of course that it is working changing the (CException *e) for a (...)
2. That the code flow never enters inside the catch clause.
By the way I won't send you the thread code...
Thanks a lot for all your help...
|
|
|
|
|
Also just a guess.
From MSDN:
<quote>
Compiler Error C2712
cannot use __try in functions that require object unwinding
You cannot have objects that require unwinding in a function with structured exception handling.
To avoid this error message, compile using the /GX- option.
The error can be avoided when using the /GX option by not having local variables or parameters with types that have destructors in a function that uses structured exception handling (SEH). Furthermore, SEH cannot be used in constructors or destructors if using /GX. Code that requires SEH can also be moved to another function in order to avoid the error.
</quote>
I would think you could eliminate the problem by using a TCHAR array instead of CStrings, that way there are no destructors to be called.
I think the problem is that if an exception is thrown, the CString destructor is unable to execute, resulting in a memory leak (at least the compiler sees it that way).
HTH
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
Hello,
First of all...
Sorry, I've been out of my office for some days...
Won't that option have any secondary effect over the program?
Thank you in advance.
|
|
|
|
|
I have some controls in a CFormView class which should only be visible when some button control is pushed. In the button click event, I added the code to display the controls as follow:
GetDlgItem(IDC_STATIC_FY)->ShowWindow(SW_SHOW);
GetDlgItem(IDC_EDIT_FY)->ShowWindow(SW_SHOW);
GetDlgItem(IDC_BUTTON_PLUS_FY)->ShowWindow(SW_SHOW);
It got compiled OK. But when I ran the application I got an assertion fail error message. I checked with the MSDN document, GetDlgItem is a member function of a CWnd class. CFormView is a CWnd class, right?
-Elizabeth
Eilzabeth
|
|
|
|
|
|
Either the controls are null or (i.e not initialised) or you are doing something noddy wrong like calling from the wrong window. If they are null, try adding a member variable for each resource id, and a DDX routine for each one. Make sure you are not calling GetDlgItem() before OnInitialUpdate();
"Life begins at 140"
|
|
|
|
|
You are right. I called a _itoa() function right before the GetDlgItem functions. I forgot to give the char variable an extra byte for the null char. That caused all sorts of problems. Thanks you.
-Elizabeth
Eilzabeth
|
|
|
|
|
I am importing OIP22.TLB in one of my header file. I am trying to connect to a oracle database which is on unix box through by VC++ application.
The following is the code I am using:
BSTR bstrDb = m_strOraDb.AllocSysString ();
BSTR bstrUser = m_strOraUser.AllocSysString ();
m_pOraDatabase = m_pOraSession->GetOpenDatabase( bstrDb, bstrUser, ORADB_DEFAULT);
m_strOradDb , m_strOraUser are Const CString
Values in m_strOraDb and m_strOraDb are : "omst", "oms/oms" (Our database name, userid/password, ORADB_DEFAULT = 0)
From above it goes into this routine of OIP22.TLI file:
#pragma implementation_key(36)
inline IDispatch * OraSession::GetOpenDatabase ( BSTR dbname, BSTR connect, long options ) {
IDispatch * _result;
_com_dispatch_method(this, 0x60010002, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&_result,
L"\x0008\x0008\x0003", dbname, connect, options);
return _result;
}
It fails just before return_result saying:
First-chance exception in MYAPP.EXE (KERNEL32.DLL): 0xE06D7363
|
|
|
|