toeb / googletest

Automatically exported from code.google.com/p/googletest
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

ASSERT_DEATH() bug on Windows #187

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Write a test containing the following:
     ASSERT_DEATH({ char foo[4]; foo[10000] = 'a'; }, "");
2. Run it under Windows
3.

What is the expected output? What do you see instead?
I expect the test to succeed, but it fails.

What version of the product are you using? On what operating system?
gtest-1.3.0 on 64-bit Windows Vista Home Premium

Please provide any additional information below.
I poked around some in a debugger and verified that this does cause an
access violation to occur.  The sub-process dies, but the status code
returned by GetExitCodeProcess() (gtest-death-test.cc:587) is 0, which
gtest interprets as a "did not die" condition (see ExitedUnsuccessfully()
in gtest-death-test.cc:162).

For grins, I tried this test:

  ASSERT_DEATH({ abort(); }, "");

It succeeds.  So it's not the case that ASSERT_DEATH() is *totally* broken
on Windows---just partially broken.  (On Vista, at least.)  Wish I could
tell you how to fix it, but it's a little beyond me at this point.  (BTW,
I'm posting this because of an unexpected death test failure in the
protobuf test suite that fails in the same way.)

Original issue reported on code.google.com by evadef...@gmail.com on 28 Aug 2009 at 5:41

GoogleCodeExporter commented 9 years ago
This is the designed behavior of ASSERT_DEATH.  What you need can be done using
ASSERT_EXIT() or EXPECT_EXIT().  Thanks.

Original comment by zhanyong...@gmail.com on 2 Sep 2009 at 4:36

GoogleCodeExporter commented 9 years ago
I think my explanation of the problem lacked precision. Please take
another look.  Here is the test case:

TEST(DeathTestBug, testSegfault)
{
    ASSERT_DEATH({ char foo[4]; foo[10000] = 'a'; }, "");
}

and here is the output when I run this test under Windows:

Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from DeathTestBug
[ RUN      ] DeathTestBug.testSegfault
Running main() from gtest_main.cc
..\death_test.cpp(5): error: Death test: { char foo[4]; foo[10000] = 'a'; }
    Result: failed to die.
 Error msg:
[  FAILED  ] DeathTestBug.testSegfault
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran.
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] DeathTestBug.testSegfault

 1 FAILED TEST

The output says "failed to die", but my debugger clearly shows that the
program dies with an 'Access violation'.  The same test, when run under
Linux, passes.  Here is the output:

Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from DeathTestBug
[ RUN      ] DeathTestBug.testSegfault
[       OK ] DeathTestBug.testSegfault
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran.
[  PASSED  ] 1 test.

It both cases, the test dies, but gtest is not able to detect the death
under Windows.  From what I can tell, the Win API call
GetExitCodeProcess() (see gtest-death-test.cc, line 587) is both
returning 1 (a success indicator) *and* a status value of 0.
ASSERT_DEATH() interprets an exit status of 0 as a "did not die"
condition, so the test is failing.  This is bug, right?

Original comment by evadef...@gmail.com on 2 Sep 2009 at 5:28

GoogleCodeExporter commented 9 years ago
I think you should use an example that dereferences a NULL pointer instead of 
trying to 
write to stack + 10000.  This is more obviously an access violating and is even 
something that someone might use EXPECT_DEATH with (as the protobuf tests did).

Original comment by kenton+protobuf@google.com on 11 Sep 2009 at 8:38

GoogleCodeExporter commented 9 years ago
Clarification:

Perhaps the wiki wasn't quite clear: the "death" in death tests is
defined as "exited with a nonzero exit code or was killed by a signal"
(http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide#Death_Tests).

In the latter case, the exit code will also be non-zero.

If the process exits with 0, there's no way for gtest to tell it apart
from a normal exit(0) or return from main().  Writing to *NULL is
undefined behavior and doesn't necessarily cause the process to exit
with non-zero.  That's why I suggested to use EXPECT_EXIT.

I've updated the wiki to make the definition of "death" more obvious.
Thanks.

If you have further questions, feel free to email the discussion group
or me (wan@google.com).  The comments in the issue tracker are not
monitored very closely.

Original comment by zhanyong...@gmail.com on 11 Sep 2009 at 9:35