Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Test and std::vector range exceptions

I test my C++ code with googletest. When a vector::_M_range_check exception is thrown because a std::vector is accessed with a wrong index, googletest reports:

C++ exception with description "vector::_M_range_check" thrown in the test body.

Great, now I'd also like to know which vector, which index and which range. How can I easily get this information, keeping the test code in googletest unit test cases?

(I almost begin long for Java with its good old IndexOutOfBoundsException...)

like image 329
clstaudt Avatar asked Jan 11 '13 15:01

clstaudt


2 Answers

If you run with this command line option then your exception will bubble all the way out:

--gtest_catch_exceptions=0

Doing this inside of a debugger will give you the exact stacktrace of the exception.

like image 51
JaredC Avatar answered Oct 21 '22 09:10

JaredC


Google Test isn't involved here. Your C++ Standard Library implementation is throwing an exception, and it's up to your C++ Standard Library implementation to decide how verbose to make its exceptions.

Since you're getting an exception, I assume that you're using std::vector::at instead of std::vector::operator[]. There are a couple of possible approaches you could take to getting more information.

First, you could replace calls to at with calls to operator[] (personally, I don't find at's exception-throwing range checking to be very useful, and it does have a performance overhead) and use your C++ Standard Library implementation's iterator debugging. For example, with g++, if I use operator[] and compile with -D_GLIBCXX_DEBUG to turn on range checking for operator[], I get an error similar to the following:

/usr/include/c++/4.3/debug/vector:237:error: attempt to subscript container
    with out-of-bounds index 0, but container only holds 0 elements.

Second, you could replace calls to at with calls to test_at or similar: (untested)

template <typename T>
T& test_at(std::vector<T>& v, size_t n) {
    // Use Google Test to display details on out of bounds.
    // We can stream additional information here if we like.
    EXPECT_LT(n, v.size()) << "for vector at address " << &v;

    // Fall back to at, and let it throw its exception, so that our
    // test will terminate as expected.
    return v.at(n);
}
like image 37
Josh Kelley Avatar answered Oct 21 '22 10:10

Josh Kelley