diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-07 05:07:50 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-07 05:07:50 +0000 |
commit | d399768afe97193573fcd0bd703203120fd10149 (patch) | |
tree | ac3fe3c158492d6bc1eccdd85acd2bb963c17d3c | |
parent | 293be45301a7ee5df291ea7aca2cf91b4d11d681 (diff) | |
download | chromium_src-d399768afe97193573fcd0bd703203120fd10149.zip chromium_src-d399768afe97193573fcd0bd703203120fd10149.tar.gz chromium_src-d399768afe97193573fcd0bd703203120fd10149.tar.bz2 |
Catch the use after free callstack of HttpServerProperties.
Will revert this change after canary push with this change.
BUG=121971
R=eroman
TEST=network unit tests browser unit tests.
Review URL: http://codereview.chromium.org/10025002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131256 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/http/http_server_properties.cc | 38 | ||||
-rw-r--r-- | net/http/http_server_properties.h | 27 | ||||
-rw-r--r-- | net/spdy/spdy_session.cc | 1 |
3 files changed, 64 insertions, 2 deletions
diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc index 5dfcebc..97768dc 100644 --- a/net/http/http_server_properties.cc +++ b/net/http/http_server_properties.cc @@ -4,6 +4,7 @@ #include "net/http/http_server_properties.h" +#include "base/debug/alias.h" #include "base/logging.h" #include "base/stringprintf.h" @@ -39,4 +40,41 @@ std::string PortAlternateProtocolPair::ToString() const { AlternateProtocolToString(protocol)); } +HttpServerProperties::HttpServerProperties() + : has_deletion_stack_trace_(false), + liveness_token_(TOKEN_ALIVE) { +} + +HttpServerProperties::~HttpServerProperties() { + // Crash if this is a double free! + CheckIsAlive(); + + // Mark the object as dead. + liveness_token_ = TOKEN_DEAD; + + if (!has_deletion_stack_trace_) { + // Save the current thread's stack trace. + has_deletion_stack_trace_ = true; + deletion_stack_trace_ = base::debug::StackTrace(); + } + + // I doubt this is necessary to prevent optimization, but it can't hurt. + base::debug::Alias(&liveness_token_); + base::debug::Alias(&has_deletion_stack_trace_); + base::debug::Alias(&deletion_stack_trace_); +} + +void HttpServerProperties::CheckIsAlive() { + // Copy the deletion stacktrace onto stack in case we crash. + base::debug::StackTrace deletion_stack_trace = deletion_stack_trace_; + base::debug::Alias(&deletion_stack_trace); + + // Copy the token onto stack in case it mismatches so we can explore its + // value. + LivenessToken liveness_token = liveness_token_; + base::debug::Alias(&liveness_token); + + CHECK_EQ(liveness_token, TOKEN_ALIVE); +} + } // namespace net diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index e61be5e..8806bb6 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h @@ -8,6 +8,7 @@ #include <map> #include <string> #include "base/basictypes.h" +#include "base/debug/stack_trace.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" #include "net/http/http_pipelined_host_capability.h" @@ -51,8 +52,8 @@ extern const char* const kAlternateProtocolStrings[NUM_ALTERNATE_PROTOCOLS]; // * Spdy Settings (like CWND ID field) class NET_EXPORT HttpServerProperties { public: - HttpServerProperties() {} - virtual ~HttpServerProperties() {} + HttpServerProperties(); + virtual ~HttpServerProperties(); // Deletes all data. virtual void Clear() = 0; @@ -113,7 +114,29 @@ class NET_EXPORT HttpServerProperties { virtual PipelineCapabilityMap GetPipelineCapabilityMap() const = 0; + //---------------------------------------------------------------------------- + // Temporary code for debugging 121971 + // TODO(rtenneti): Delete this when done investigating. + //---------------------------------------------------------------------------- + void CheckIsAlive(); + //---------------------------------------------------------------------------- + private: + //---------------------------------------------------------------------------- + // Temporary code for debugging 121971 + // TODO(rtenneti): Delete this when done investigating. + //---------------------------------------------------------------------------- + // Value to indicate whether this instance is alive or dead. + enum LivenessToken { + TOKEN_ALIVE = 0xcd9e38, + TOKEN_DEAD = 0xDEADBEEF, + }; + + bool has_deletion_stack_trace_; + base::debug::StackTrace deletion_stack_trace_; + LivenessToken liveness_token_; + //---------------------------------------------------------------------------- + DISALLOW_COPY_AND_ASSIGN(HttpServerProperties); }; diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 9da8136..40abd94 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -1897,6 +1897,7 @@ void SpdySession::RecordHistograms() { stalled_streams_ > 0 ? 1 : 0, 2); if (received_settings_) { + http_server_properties_->CheckIsAlive(); // Enumerate the saved settings, and set histograms for it. const SettingsMap& settings_map = http_server_properties_->GetSpdySettings(host_port_pair()); |