Issue with Root on Windows and TMessage (debug vs release)

I am having an issue with TMessage and windows (VS 2005), debug vs release mode. The ROOT version 5.26.

I have section of code that uses TSockets to send a message to a server and waits for a response. The response should come back as a kMESS_OBJECT. A snippet of the code is shown below.

[code]TMessage *rmess;

if ((iRes = m_socket->Select( TSocket::kRead, kiSocketTimeout )) > 0) {
if (m_socket->Recv(rmess) <= 0)
{
m_bSocketIsValid = false;
delete m_socket;
m_socket = NULL;
iResult = CYT_CONNECTION_CLOSED;
break;
}
else
{
if (rmess->What() == kMESS_OBJECT)
{
(we process the message here)[/code]

In debug mode the program works just fine. In release mode however rmess->What() returns kMess_OK and not kMess_OBJECT. The actual size of the data is correct for the responding message in both release and debug mode.

I also noticed that rmess->What() code looked different based on whether I built in Release or Debug mode (same ROOT Libs used, despite build type). Note that in release mode I have turned off the optimization.

[code]Call in Debug Mode:
UInt_t What() const { return fWhat; }
00467690 push ebp
00467691 mov ebp,esp
00467693 sub esp,44h
00467696 push ebx
00467697 push esi
00467698 push edi
00467699 mov dword ptr [ebp-4],ecx
0046769C mov eax,dword ptr [this]
0046769F mov eax,dword ptr [eax+8Ch]
004676A5 pop edi
004676A6 pop esi
004676A7 pop ebx
004676A8 mov esp,ebp
004676AA pop ebp
004676AB ret

Call in Release Mode:

00431940 push ebp
00431941 mov ebp,esp
00431943 push ecx
00431944 mov dword ptr [ebp-4],ecx
00431947 mov eax,dword ptr [this]
0043194A mov eax,dword ptr [eax+84h]
00431950 mov esp,ebp
00431952 pop ebp
00431953 ret [/code]
The offset in the release mode (84h) points to 1 (success or OK) but at offset 8Ch the value of 4 does exist in both cases. Is there something I am missing about the TMessage class or is it something more basic that we are doing wrong with ROOT ?

Any guidance would be appreciated.

Thanks

Hi,

First of all, the compiler flags of your application must match the one of Root libs (especially debug/release). You must not mix debug/release flags (even if it may work by chance). Could you try this first and let me know, please?
If not, please provide a running piece of code reproducing the problem.

Cheers, Bertrand.

Bertrand,

I had run the Release version of Root (from MSI) against my release build last week with similar results with the Release image (the TMessage object is not reported as Object).

I will try to make a minimum program to replicate the issue.

Thanks again,

Glen

One other observation I had with this issue.

When looking at the code using the ROOT debug I noticed that when linked to my release code the underlying fClass did not have and fImplFilename where as with the Debug code it did. fDeclFilename was accurate in both cases. This was after received the same message from the far side (server).

Is this a red herring or a pointer to something more sinister in what I am doing ?

Thanks,

Glen

Hi,

ImplFileName is set via the ClassImp() CPP macro. The fact that once you have it and once you don’t is indeed a symptom for something - either the libraries are not identical in both cases or the dictionary is not properly initialized in the case where ImplFileName is not set. It might be that some optimization removes parts / all of the dictionary from the library or when linking the .lib to a .exe. You might have to use the linker flag -include:_G__cpp_setup[dictname] where [dictname] is the output filename for your dictionary without filename extension, e.g. -include:_G__cpp_setupDict for the dictionary generated with rootcint -f Dict.cxx …

As before we will need a working example to debug it.

Cheers, Axel.

Thank you for the feedback,

I did rebuild Root using VS 2005 and the symptom I saw went away. I do have some issues with memory not properly being freed (within Root I beleive) on exit but I am sure that is an educational process on my part to solve that.

I am trying right now to recreate the memory issue on a much smaller application.

Thank you once again,

Glen

Axel, Bertrand and team.

I have recreated the “ memory leak on exit “ issue with a much smaller application than I previously had (attached). This is VS 2005 and with a ROOT debug image build under the same environment.

This application is MFC and creates a class of TApplication. When exiting I leak memory. We have a non-MFC application here that does more but appears to work fine with a similar use of TApplication. In the larger appliciation we did call ->Terminate but that does not make a difference in the symptoms.

I am currently looking at the MFC build to see if there is a bad mix of windows and non-windows includes etc to see if this is a cause. Being relatively new at ROOT I am not sure where to attack this from.
I will attach the source tree for the smaller MFC app. If you have any suggestions on where I should be looking it would greatly be appreciated.

Thank you once again for all your support.
Glen
roottest.zip (35.3 KB)

Hi,

apologies for my laziness - but I assume if you can tell that there is a memory leak you can also tell where it leaks? Can you send the list? We intentionally leak some objects, I just want to cross check that we’re not talking about the intentional leaks.

Cheers, Axel.

Not a problem Axel, thankful for the help. I will collect this information and see if it aligns with your expectations. I suspect something more since it basically throws the debugger (VS 2005) into a tail spin on exit.

I have attached a zip file that contains just part of the reporting of the leaks on exit. Based on some of the files mentioned I still assume it is something we are doing globally with Root since most of the root files mentioned we never directly make use of. Any ideas or directions would greatly be appreciated.

Also to let you know the libraries were build with the Root Builder tool configurations (also VS2005/debug) but I am still not 100% convinced that this is not the cause of my troubles

Glen
leakfragment.zip (139 KB)

Hi Glen,

Unfortunately the leak report you posted is not a format that let us know what the leaks are. Namely in order to ascertain whether a memory area is intentionally left undeleted at the end of the process, we would need to know where in the code the leaked memory area were allocated.

More important to your case, do you have a systemic memory growth during the execution of your program?

Cheers,
Philippe.

Philippe,

I do not have a continual growth of memory utilization during run time. I did check for this using UMDH. What I have instead is a report (as attached) from MSFT VS2005 reporting memory not being freed on exit. I do not have to do anything but force the root code to be loaded then exit.

The DLLs I load were built using the root builder (for the configuration files,etc) and VS 2005. Right now I am suspecting this more than anything else as I have looked at examples of other MFC root implementations and we appear to do things in a similar fashion. I went to this build because the debug version of the 5.26 installable image (build for VS 2008) would crash on exit. I was told to rebuild with the correct compiler.

It should also be noted that during runtime all the libraries work fine for both images.

I will do more testing around the dll loads/unloads if you think that would help or is there something build specific for the root code that I can validate ?

Thanks,

Glen

[quote]What I have instead is a report (as attached) from MSFT VS2005 reporting memory not being freed on exit. [/quote]As mentioned by Axel, we intentionally do not delete all the object at the end of the process both to avoid problem with order of deletion/library unloading and to avoid wasting time running unnecessary code.

[quote]I do not have a continual growth of memory utilization during run time.[/quote]Then there is most likely no unexpected ‘leak’.

[quote] I went to this build because the debug version of the 5.26 installable image (build for VS 2008) would crash on exit. [/quote]Do you still get a crash on exit? If not, the problem is probably solved.

[quote]I will do more testing around the dll loads/unloads if you think that would help or is there something build specific for the root code that I can validate ?[/quote]To validate that the build is correct you could try to run some of the example in $ROOTSYS/tutorials or build and execute some of test in $ROOTSYS/test (in particular stress.exe).

Cheers,
Philippe.

Folks,

I have continued my investigation with the debug image. Right now I have to intercept Visual Studio error messages on program exit or the program will exit only after a large amount of error reporting (some of what I showed in my earlier posts). There are two problems with this approach. The first is that I am still not sure if I have done something wrong to create this issue. The second is that by masking the errors I also mask any that I may of created in my program unrelated to root.

I have made a minimal program (debug version) with VS 2008 and using the correct Debug MSI from the distrubution pages. The application is MFC based but has a simple few steps to recreate the problem. This is core of the code:

[color=#FF0000]CroottestApp::CroottestApp()
{
Int_t argc = 1;
char *argv[] = {“roottest”, NULL};
TApplication theApp(“App”, &argc, argv);
theApp.Terminate(0);

}[/color]

Can you tell me what is the expected behavior in debug mode and any suggestions on migitgating this issue ? I am hoping it is something we are doing as right now I am concerned I will still have issues in the future that are related indirectly on how I am using this code.

Many thanks,

Glen
roottestvs2008.zip (47.2 KB)