DecodeBufferDeathTest.NonNullBufferRequired failing with SEGV_MAPERR |
||||
Issue description
As seen here:
DecodeBufferDeathTest.NonNullBufferRequired (run #1):
[ RUN ] DecodeBufferDeathTest.NonNullBufferRequired
[WARNING] ../../testing/gtest/src/gtest-death-test.cc:834:: Death tests use fork(), which is unsafe particularly in a threaded context. For this test, Google Test detected 5 threads.
../../net/http2/decoder/decode_buffer_test.cc:331: Failure
Death test: { DecodeBuffer b(nullptr, 3); }
Result: died but not with expected error.
Expected: nullptr
Actual msg:
[ DEATH ] Received signal 11 SEGV_MAPERR 000000000000
[ DEATH ] [0x000119fd64fe]
...
Causing failures in Mac builds and maybe more.
Potential culprit CL [2] is already being reverted [3].
[1] https://luci-logdog.appspot.com/v/?s=chromium%2Fbb%2Fchromium.mac%2FMac10.9_Tests__dbg_%2F33681%2F%2B%2Frecipes%2Fsteps%2Fnet_unittests%2F0%2Flogs%2FDecodeBufferDeathTest.NonNullBufferRequired%2F0
[2] https://codereview.chromium.org/2293613002
[3] https://codereview.chromium.org/2554683003/
,
Dec 7 2016
I don't think this is caused by the overload I introduced, as the previously existing one is being used in the backtrace. The problem is that this operator<< overload is being called:
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
const char* s );
and its behavior is undefined when |s| is null.
thakis/jbroman: I could see if some sort of template black magic only for chars would work here, but something like "if (std::is_pointer<T>::value && !v) (*os) << "null pointer" is a lot easier at the expense of being a runtime check. Do you guys have any preference?
,
Dec 7 2016
Dunno, a nullptr_t overload is all that's needed maybe?
,
Dec 7 2016
Why wasn't this needed previously? But crashing on nullptr doesn't seem unreasonable to me either. Just say DCHECK(foo != nullptr)
,
Dec 7 2016
We already have a nullptr_t overload: // We need an explicit overload for std::nullptr_t. BASE_EXPORT void MakeCheckOpValueString(std::ostream* os, std::nullptr_t p); And I think this problem has always been present. The crash only happens with signed/unsigned/nothing character pointers that end up using these overloads: http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2
,
Dec 7 2016
Yeah, the right side should deduce to nullptr_t, but the type of the left side is clearly "const char*", and it's the conversion of that to string that is undefined (as one would expect). Just "DCHECK(buffer)" will suffice.
,
Dec 7 2016
OK, so is it fine not to add any other checks or overloads to the logging code?
,
Dec 7 2016
Yes.
,
Dec 7 2016
Personally that SGTM, I'm not convinced it's worth adding an overload for char* (with various cv qualifiers) just so that it deals with nullptr. Don't know how base/ owners (thakis@?) feel.
,
Dec 7 2016
Alright, reassigning this to bnc@ then.
,
Dec 7 2016
Thank you y'all very much for looking into this, I appreciate your efforts. I have already landed the workaround at https://crrev.com/2553223002, the one proposed at comment #4. Therefore I am closing this as Fixed. |
||||
►
Sign in to add a comment |
||||
Comment 1 by b...@chromium.org
, Dec 6 2016Owner: raphael....@intel.com