chronos-tachyon / googletest-bazel

Fork of googletest that uses bazel.build
https://github.com/google/googletest
BSD 3-Clause "New" or "Revised" License
4 stars 4 forks source link

Possible double freeing when using ::testing::MatchesRegex(const std::string&) #424

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
The attached test code when linked with DUMA built on MinGW aborts suspecting 
double freeing. See the output in the attached test_output.txt which also shows 
how I built the test code on MinGW.

DUMA seems to work for me otherwise and reported errors appropriately so far, 
although I haven't extensively tested it.

This error is not present if I don't use ::testing::MatchesRegex and the test 
executables run fine.

For building DUMA for MinGW follow the instructions below:

1) Obtain http://sourceforge.net/projects/duma/ (at the time of documenting 
this it was 2.5.15)
2) There was a bug that prevented building DUMA on MinGW. See 
http://sourceforge.net/tracker/?func=detail&aid=2793791&group_id=149725&atid=775
376. In summary doing the below would fix it (unless you are on a more recent 
version where the bug is already fixed)
2.a) Open the file print.c
2.b) insert #include<fcntl.h> on line 44
Further edit the GNUMakefile 
2.c) set DUMA_OPTIONS to  -DDUMA_NO_THREAD_SAFETY (on line 69) 
2.d) under OSTYPE msys (line 112) leave the defaults except the following 
options
    RM=rm
    RMFORCE=rm -f
    CFLAGS=-g -gdb3 -O0
    CPPFLAGS=-g -gdb3 -O0

3) Open windows command prompt (cmd.exe) and set PATH to include <MinGW bin 
directory> as well as <Msys bin directory> (if you have multiple versions of 
Mingw and msys installed set the order such that the version you want comes 
first)
4) change directory to the folder containing the extracted DUMA
5) Run the following:
$ mingw32-make OSTYPE=msys

This should build libduma.a (also some tests but they didn't work for me)
$ cp libduma.a to <MinGW lib directory>

Original issue reported on code.google.com by aravind....@gmail.com on 14 Dec 2012 at 9:57

Attachments:

GoogleCodeExporter commented 9 years ago
duma_2_5_15.tar contains the DUMA sources as obtained from 
http://duma.sourceforge.net/ with some modifications as stated in the original 
post, to enable it build on MinGW. It also contains the libduma.a that was used 
to reproduce the above problem.

Original comment by aravind....@gmail.com on 14 Dec 2012 at 10:06

Attachments:

GoogleCodeExporter commented 9 years ago
MinGW used is the latest with GCC 4.7.2. The associated gtest libs and include 
files are attached here. NOTE: libgmock.a here contains both gtest and gmock 
object files.

Original comment by aravind....@gmail.com on 14 Dec 2012 at 10:08

Attachments:

GoogleCodeExporter commented 9 years ago
A slight modification to the test_code.cpp, just to make it clear that it is 
the destructor for the matcher object causing this double freeing. 

Output shows that EXPECT_THAT has returned fine.

DUMA 2.5.15 (static library, NO_THREAD_SAFETY, EXPLICIT_INIT)
Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
Copyright (C) 2002-2008 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Try1
[ RUN      ] Try1.Test_Try1
I am fine till here..!
test_code.cpp:22: Failure
Value of: " {  { 10, 0x00, RPT }, ( blah_t ) } "
Expected: matches regular expression "^\\s*\\{\\s*\\{\\s*10\\s*\\,\\s*0x00\\s*\\
,\\s*RPT\\s*\\}\\s*\\,\\s*\\(\\s*blah_t\\s*\\*\\)\\s*\\s*\\}\\s*$"
  Actual: " {  { 10, 0x00, RPT }, ( blah_t ) } \0" (of type char [37])
am I fine still, here..?

DUMA Aborting: free(8923a8): address not from DUMA or already freed.

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

The call stack extracted by setting breakpoint on abort is as below:

#0  0x00434b98 in abort ()
#1  0x00405492 in DUMA_Abort (
    pattern=0x4b6d14 "free(%a): address not from DUMA or already freed.")
    at print.c:292
#2  0x00403e76 in _duma_deallocate (address=0x892cb0, protectAllocList=1,
    allocator=EFA_FREE,
    filename=0x4b6500 "UNKNOWN (use #include \"duma.h\")", lineno=0)
    at duma.c:1759
#3  0x00404580 in _duma_free (baseAdr=0x892cb0,
    filename=0x4b6500 "UNKNOWN (use #include \"duma.h\")", lineno=0)
    at duma.c:2020
#4  0x00404d1b in free (address=0x892cb0) at duma.c:2408
#5  0x00412d1c in testing::internal::RE::~RE() ()
#6  0x00438873 in testing::internal::linked_ptr<testing::internal::RE const>::de
part (this=0x22fcb8)
    at c:/perforce/bc/bluelab63/bluecoretest/unittest/tools/mingw/bin/../lib/gcc
/mingw32/4.7.2/../../../../include/gtest/internal/gtest-linked_ptr.h:195
#7  0x0043891f in testing::internal::linked_ptr<testing::internal::RE const>::~l
inked_ptr (this=0x22fcb8, __in_chrg=<optimized out>)
    at c:/perforce/bc/bluelab63/bluecoretest/unittest/tools/mingw/bin/../lib/gcc
/mingw32/4.7.2/../../../../include/gtest/internal/gtest-linked_ptr.h:143
#8  0x0043c00b in testing::internal::MatchesRegexMatcher::~MatchesRegexMatcher
    (this=0x22fcb8, __in_chrg=<optimized out>)
    at c:/perforce/bc/bluelab63/bluecoretest/unittest/tools/mingw/bin/../lib/gcc
/mingw32/4.7.2/../../../../include/gmock/gmock-matchers.h:1065
#9  0x00436fd3 in testing::PolymorphicMatcher<testing::internal::MatchesRegexMat
cher>::~PolymorphicMatcher (this=0x22fcb8, __in_chrg=<optimized out>)
    at c:/perforce/bc/bluelab63/bluecoretest/unittest/tools/mingw/bin/../lib/gcc
/mingw32/4.7.2/../../../../include/gmock/gmock-matchers.h:317
#10 0x00401592 in Try1_Test_Try1_Test::TestBody (this=0x1810ff8)
    at test_code.cpp:23
#11 0x0043da8b in void testing::internal::HandleSehExceptionsInMethodIfSupported
<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*)
    ()
#12 0x0043d67f in void testing::internal::HandleExceptionsInMethodIfSupported<te
sting::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#13 0x00409d2f in testing::Test::Run() ()
#14 0x0040a3b3 in testing::TestInfo::Run() ()
#15 0x0040a8d0 in testing::TestCase::Run() ()
#16 0x0040e4b6 in testing::internal::UnitTestImpl::RunAllTests() ()
#17 0x0043da13 in bool testing::internal::HandleSehExceptionsInMethodIfSupported
<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (
testing::internal::UnitTestImpl::*)(), char const*) ()
#18 0x0043d36b in bool testing::internal::HandleExceptionsInMethodIfSupported<te
sting::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (tes
ting::internal::UnitTestImpl::*)(), char const*) ()
#19 0x0040d7b7 in testing::UnitTest::Run() ()
#20 0x0040166b in main (argc=1, argv=0x892c90) at test_code.cpp:32

Original comment by aravind....@gmail.com on 14 Dec 2012 at 1:34

Attachments:

GoogleCodeExporter commented 9 years ago
I have tried to run this code under a couple of memory checkers I have ready 
access to (Valgrind/memcheck and ASAN) and they reported all clear, so I 
suspect a false positive.

The reason for a false positive is most often the test program that used 
different compiler settings - or even a different ABI - than a library it 
links. Please make sure that libraries you use are built with the same compiler 
settings. It's best not use a prebuilt version of Google Mock but to build one 
as part of your tests.

Original comment by vladlosev on 18 Dec 2012 at 8:57

GoogleCodeExporter commented 9 years ago
Thanks for your time in testing it. That could be it. I've compiled the 
gmock/gtest library without the "-std=gnu++11" flag, but then all my test 
sources are being compiled with that flag. I didn't think that would be an 
issue.

Also while linking the test executable I link with -static-libgcc and 
-static-libstdc++ just so that the test runs in windows command prompt (i.e. 
not in msys shell where library paths are set appropriately to locate the 
corresponding dlls). However, I guess that shouldn't be a problem. 

I will post back with results.

Original comment by aravind....@gmail.com on 19 Dec 2012 at 11:11

GoogleCodeExporter commented 9 years ago
As for my earlier post, I lied about compiling the gmock/gtest library without 
the "-std=gnu++11". I've noticed (from a log) that I did compile with that 
option. 

I am now compiling gmock/gtest sources along with my tests (still libduma.a is 
pre-
compiled though) and the problem did not go away (and the location of the 
problem didn't change).

Not sure what to do, apart from dropping DUMA and finding an alternative memory 
analysis tool that works on MinGW.

The attached file shows the build output as well as gdb backtrace.

Original comment by aravind....@gmail.com on 19 Dec 2012 at 3:14

Attachments:

GoogleCodeExporter commented 9 years ago
Your output shows that you are compiling your code in debug mode (-O0 -g3) but 
without -DENABLE_DUMA. Try synchronizing the compiler options.

Original comment by vladlosev on 18 Jan 2013 at 8:16

GoogleCodeExporter commented 9 years ago
Vladlosev, Thanks for your response.

ENABLE_DUMA is a macro I have defined in the file gmock_main_cust.cpp, which 
includes/precludes a call to duma_init() in the main(). This gets called prior 
to initlaizing GoogleMock, see the excerpt from gmock_main_cust.cpp below:

#ifdef ENABLE_DUMA
extern "C" void duma_init(void); // Currently disabled see Issue 424 
http://code.google.com/p/googletest/issues/detail?id=424
#endif

GTEST_API_ int main(int argc, char** argv)
{
#ifdef ENABLE_DUMA
    duma_init(); // Currently disabled see Issue 424 http://code.google.com/p/googletest/issues/detail?id=424
#endif
    ::testing::InitGoogleMock(&argc, argv);
    /* Get a list of event listeners */
    ::testing::TestEventListeners& listeners =
            ::testing::UnitTest::GetInstance()->listeners();
    listeners.Append(new TeamCityEventOutput());
    if ( RUN_ALL_TESTS() ) /* Do not return failure, as the build will stop, without generating coverage */
    {
        std::cerr << "Some of the tests have failed" << std::endl;
    }
    return 0;
}

Regarding mis-synchronised compiler options, good catch. Now I have ensured 
that the compiler options are synchronised but still no joy.

More info in the attached file.

Original comment by aravind....@gmail.com on 21 Jan 2013 at 11:32

Attachments: