Malloc error with std::string and TFile simultaneously

Hi, I recently updated from root 5.22 to root 5.26, and I’m finding a very odd issue. I’m compiling the following code using g++ 4.4.1 in ubuntu 9.10:

#include <iostream>            
#include <string>              
#include "root/TFile.h"        

using namespace std;           

int main(){                    
  TFile * file = new TFile("Topmix.root"); 
  string teststr("test");
  cout << teststr << endl;     
  return 0;                    
}

And I get the following error when running the code:

I did not get this problem in 5.22. In fact, I kept my old root directory after compiling 5.26, and switched it back, and the problem went away.

I get a similar error if I use the c_str() method of std::string. I’m guessing most other uses of std::string have similar issues. The problem goes away if I comment out the TFile line.

Any suggestions? Thanks![/quote][/code]

Forgot to mention, in case its important. I’m using this version of gcc:

Hi, any ideas on this?

Thanks,
Caleb

Hi,

I just tried on a virtual machine with svn trunk and had no problem with your code:

~/rootdev$ g++ callampen.cxx -o callampen `root-config --cflags --libs` ~/rootdev$ ./callampen Error in <TFile::TFile>: file Topmix.root does not exist test ~/rootdev$ ~/rootdev$ gcc --version gcc (Ubuntu 4.4.1-4ubuntu8) 4.4.1
Did you compile root yourself?

Cheers,
Bertrand.

Hi,

I agree, that’s extremely weird. Are you sure LD_LIBRARY_PATH and the build of your binary are consistent, i.e. do you really pick up the ".so"s that correspond to the headers? Running with valgrind should give you some more info on what’s causing the memory corruption.

Cheers, Axel.

Yes, I compiled ROOT myself (they don’t have a pre-packaged version for Ubuntu of the most recent version that I know of).

The LD_LIBRARY_PATH points to the correct directory ${HOME}/root/libs

I’ve attached output from valgrind. I’m not much of an expert in reading valgrind logs, but it seems the errors are in the TUrl class, at least the first error appears there.

EDIT: Attachement doesn’t seem to be loading. The contents aren’t too long, so I’ll just put them here:

[quote]
==11412== Memcheck, a memory error detector
==11412== Copyright © 2002-2009, and GNU GPL’d, by Julian Seward et al.
==11412== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==11412== Command: ./test.exe
==11412==
==11412== Invalid write of size 4
==11412== at 0x041e5f06: TUrl::SetUrl(char const*, bool) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x041e66b0: TUrl::TUrl(char const*, bool) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x04e051c3: TFile::TFile(char const*, char const*, char const*, int) (in /home/lampen/root/lib/libRIO.so)
==11412== by 0x08048cf7: main (test.cpp:8)
==11412== Address 0x678bba4 is 0 bytes after a block of size 412 alloc’d
==11412== at 0x04025390: operator ((null):0)
==11412== by 0x041b54fa: TStorage::ObjectAlloc(unsigned int) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x08048e45: TObject::operator ((null):0)
==11412== by 0x08048ccb: main (test.cpp:8)
==11412==
==11412== Invalid write of size 4
==11412== at 0x04e051cf: TFile::TFile(char const*, char const*, char const*, int) (in /home/lampen/root/lib/libRIO.so)
==11412== by 0x08048cf7: main (test.cpp:8)
==11412== Address 0x678bba8 is 4 bytes after a block of size 412 alloc’d
==11412== at 0x04025390: operator ((null):0)
==11412== by 0x041b54fa: TStorage::ObjectAlloc(unsigned int) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x08048e45: TObject::operator ((null):0)
==11412== by 0x08048ccb: main (test.cpp:8)
==11412==
==11412== Invalid write of size 4
==11412== at 0x04e051d9: TFile::TFile(char const*, char const*, char const*, int) (in /home/lampen/root/lib/libRIO.so)
==11412== by 0x08048cf7: main (test.cpp:8)
==11412== Address 0x678bbac is 8 bytes after a block of size 412 alloc’d
==11412== at 0x04025390: operator ((null):0)
==11412== by 0x041b54fa: TStorage::ObjectAlloc(unsigned int) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x08048e45: TObject::operator ((null):0)
==11412== by 0x08048ccb: main (test.cpp:8)
==11412==
==11412== Invalid read of size 4
==11412== at 0x04e0cea8: TFile::~TFile() (in /home/lampen/root/lib/libRIO.so)
==11412== by 0x041fc1b9: TCollection::GarbageCollect(TObject*) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x042030cf: TList::Delete(char const*) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x041af249: TROOT::~TROOT() (in /home/lampen/root/lib/libCore.so)
==11412== by 0x0612f427: __cxa_finalize (cxa_finalize.c:56)
==11412== by 0x041600f3: ??? (in /home/lampen/root/lib/libCore.so)
==11412== by 0x046059cf: ??? (in /home/lampen/root/lib/libCore.so)
==11412== by 0x0400df45: _dl_fini (dl-fini.c:248)
==11412== by 0x0612f05e: __run_exit_handlers (exit.c:78)
==11412== by 0x0612f0ce: exit (exit.c:100)
==11412== by 0x06116b5d: ??? (below main:0)
==11412== Address 0x678bba8 is 4 bytes after a block of size 412 alloc’d
==11412== at 0x04025390: operator ((null):0)
==11412== by 0x041b54fa: TStorage::ObjectAlloc(unsigned int) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x08048e45: TObject::operator ((null):0)
==11412== by 0x08048ccb: main (test.cpp:8)
==11412==
==11412== Invalid read of size 4
==11412== at 0x04e0cec4: TFile::~TFile() (in /home/lampen/root/lib/libRIO.so)
==11412== by 0x041fc1b9: TCollection::GarbageCollect(TObject*) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x042030cf: TList::Delete(char const*) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x041af249: TROOT::~TROOT() (in /home/lampen/root/lib/libCore.so)
==11412== by 0x0612f427: __cxa_finalize (cxa_finalize.c:56)
==11412== by 0x041600f3: ??? (in /home/lampen/root/lib/libCore.so)
==11412== by 0x046059cf: ??? (in /home/lampen/root/lib/libCore.so)
==11412== by 0x0400df45: _dl_fini (dl-fini.c:248)
==11412== by 0x0612f05e: __run_exit_handlers (exit.c:78)
==11412== by 0x0612f0ce: exit (exit.c:100)
==11412== by 0x06116b5d: ??? (below main:0)
==11412== Address 0x678bbac is 8 bytes after a block of size 412 alloc’d
==11412== at 0x04025390: operator ((null):0)
==11412== by 0x041b54fa: TStorage::ObjectAlloc(unsigned int) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x08048e45: TObject::operator ((null):0)
==11412== by 0x08048ccb: main (test.cpp:8)
==11412==
==11412== Invalid read of size 4
==11412== at 0x041e4032: TUrl::~TUrl() (in /home/lampen/root/lib/libCore.so)
==11412== by 0x04e0d005: TFile::~TFile() (in /home/lampen/root/lib/libRIO.so)
==11412== by 0x041fc1b9: TCollection::GarbageCollect(TObject*) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x042030cf: TList::Delete(char const*) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x041af249: TROOT::~TROOT() (in /home/lampen/root/lib/libCore.so)
==11412== by 0x0612f427: __cxa_finalize (cxa_finalize.c:56)
==11412== by 0x041600f3: ??? (in /home/lampen/root/lib/libCore.so)
==11412== by 0x046059cf: ??? (in /home/lampen/root/lib/libCore.so)
==11412== by 0x0400df45: _dl_fini (dl-fini.c:248)
==11412== by 0x0612f05e: __run_exit_handlers (exit.c:78)
==11412== by 0x0612f0ce: exit (exit.c:100)
==11412== by 0x06116b5d: ??? (below main:0)
==11412== Address 0x678bba4 is 0 bytes after a block of size 412 alloc’d
==11412== at 0x04025390: operator ((null):0)
==11412== by 0x041b54fa: TStorage::ObjectAlloc(unsigned int) (in /home/lampen/root/lib/libCore.so)
==11412== by 0x08048e45: TObject::operator ((null):0)
==11412== by 0x08048ccb: main (test.cpp:8)
==11412==
==11412== HEAP SUMMARY:
==11412== in use at exit: 2,737,464 bytes in 43,074 blocks
==11412== total heap usage: 432,365 allocs, 389,291 frees, 15,672,405 bytes allocated
==11412==
==11412== For a detailed leak analysis, rerun with: --leak-check=full
==11412==
==11412== For counts of detected and suppressed errors, rerun with: -v
==11412== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 63 from 8)
==11412==
[/quote][/quote]

Hi,

I have a Ubuntu 9.10 setup and using your test program, I cannot reproduce neither the malloc error report nor the valgrind result. Can you write in one post the test program, compile step and valgrind command showing the errors. Also did you change and system.rootrc settinfs?

Cheers, Fons.

Hmmm… so I have a unique setup issue probably. This is a vanilla install so far as I can tell. I’ve never touched the contents of the root configuration files.

One question. How does root-config --cflags --libs figure things out? I had a previous installation of 5.18. When installing the new verions, I simply moved the ~/root directory with 5.22 to ~/oldRoot, and put the 5.26 installation at ~root. I figured, with a new shell, that this would work fine and compilations would point to the correct place. However, I don’t know quite how root-config works, so I suppose I could have something confused.

The contents of my session are:

Just check what root-config --libs prints. This should match the location of your new ROOT built. I did what you described and cannot repeat the issue:

So, I can fix it by just removing the using namespace std; from the top of the file. I’m interested if anyone has any ideas why this made a difference. This code runs fine:

#include <iostream>
#include <string>
#include "TFile.h"

//using namespace std;           

int main(){
  TFile * file = new TFile("Topmix.root");
  std::string tstr("test");
  std::cout << tstr << std::endl;
  return 0;
}

Hi,

In the broken case, what did root-config --cflags --libs returns (and how does it compare to LD_LIBRARY_PATH?

Philippe.

My previous post was wrong. I still get this problem in a more complicated program (exact same error message). However, I’m having trouble reproducing it in a simple short test case this time.

To answer the last post:

$root-config --cflags --libs         
-pthread -m32 -I/home/lampen/root/include -L/home/lampen/root/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic

and

$echo $LD_LIBRARY_PATH /home/lampen/root/lib [/code]

[quote] I still get this problem in a more complicated program (exact same error message). However, I’m having trouble reproducing it in a simple short test case this time. [/quote]Since the result is quite bizarre (all your environment seems correct and unless there was a problem with the make or the install all should be fine; by the way how did you configure root?), I am guessing that there is an important (build?) variable that change between your simple and your complex program (for example did you verify that all .o files and library have been regenerated after you switched root versions?). So the best way is still most likely to try to find a way to reproduce the problem with a small example so that we can also attempt to reproduce it.

Cheers,
Philippe.

I used the instructions here to set up root this time:
twiki.cern.ch/twiki/bin/view/Sa … ll804#ROOT
Using this configuration suggested at the bottom of the section:

Okay, I fixed it, but now have a new problem.

First the fix. I corrected the problem by simply rearranging the order of my include statements. I don’t know why this fixed it.

Originally

#include <Riostream.h>
#include <iostream//>
#include <sstream>
#include <string>
#include "root/TROOT.h"
//My personal web page generator:
#include "/home/lampen/Dropbox/WebPageMaker/WebPageMaker.h"
#include <sys/stat.h>

Version that works:

#include <Riostream.h>
#include "root/TROOT.h"
#include <iostream>           
#include <string>             
#include "TFile.h"       
#include <fstream>
#include <vector>
#include "/home/lampen/Dropbox/WebPageMaker/WebPageMaker.h"
#include <sys/stat.h>

That has fixed the my crash occurring when I tried to use an ifstream object with an instantiated WebPageMaker class. Obviously my class is the problem, however the problem didn’t occur in root 5.22, which is why I ask the expertise here.

Now I have a new problem. This one is very odd, and simple, in that initializing a TCanvas causes a crash. The following program doesn’t work:

#include <iostream>
#include "root/TCanvas.h"

int main(int argc, char * argv[]) {

  std::cout << "test1" << std::endl;
  TCanvas *cnv = new TCanvas("cnv","cnv",700,500);
  std::cout << "test2" << std::endl;

  return 0;
}

resulting in the log output:

I should repeat that if I switch back to 5.22, all of these problems go away:

I also should mention that the benchmark.C macro with root works, as does CINT work. It seems these problems only occur with compiled programs.

In my larger program, when I try to instantiate a TCanvas, for some reason I get more backtrace info. I assume its the same issue as the short program, so I’ll include it here in case people find it illuminating:

#include "root/TROOT.h" .... #include "TFile.h" This is suspicious. Why do you include some root header file prefixed with ‘root/’ and some without? Are you sure you are always using a consistent set of header file. I bet that the problem is that you have 2 install of ROOT one where the headers are in something/root/ and one where the header are in somewhere_else/include and that both ‘something’ and ‘somewhere_else/include’ and in the include path (i.e -I…) [of course you might actually be using a variant of the issue].

Such a discrepancy could explain both the original malloc error and the fact that it goes away if you re-arrange the header as it would mean that different compilation unit think that the same classes have different layout and/or size … resulting in random crappy behavior of course !.

Cheers,
Philippe.

PS. For example maybe you have ROOT header files in /usr/include/root