Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

TS-2019 Fix the "vector inconsistency" errors.

  • Loading branch information...
commit af3e7aa871740e85b0e610b3fd4c2dd741bfe52a 1 parent be1f214
@SolidWallOfCode SolidWallOfCode authored
Showing with 55 additions and 23 deletions.
  1. +2 −0  CHANGES
  2. +23 −2 iocore/cache/CacheRead.cc
  3. +30 −21 proxy/hdrs/HTTP.cc
View
2  CHANGES
@@ -1,6 +1,8 @@
-*- coding: utf-8 -*-
Changes with Apache Traffic Server 5.0.0
+ *) [TS-2019] Fix the "vector inconsistency" errors.
+
*) [TS-2585] Add overridable configs support to regex_remap plugin.
Author: Ethan Lai <yzlai@yahoo.com>
View
25 iocore/cache/CacheRead.cc
@@ -1061,12 +1061,33 @@ CacheVC::openReadStartHead(int event, Event * e)
#ifdef HTTP_CACHE
CacheHTTPInfo *alternate_tmp;
if (frag_type == CACHE_FRAG_TYPE_HTTP) {
+ uint32_t uml;
ink_assert(doc->hlen);
if (!doc->hlen)
goto Ldone;
- if (vector.get_handles(doc->hdr(), doc->hlen) != doc->hlen) {
+ if ((uml = vector.get_handles(doc->hdr(), doc->hlen)) != doc->hlen) {
if (buf) {
- Note("OpenReadHead failed for cachekey %X : vector inconsistency with %d", key.word(0), doc->hlen);
+ HTTPCacheAlt* alt = reinterpret_cast<HTTPCacheAlt*>(doc->hdr());
+ int32_t alt_length = 0;
+ // count should be reasonable, as vector is initialized and unlikly to be too corrupted
+ // by bad disk data - count should be the number of successfully unmarshalled alts.
+ for ( int32_t i = 0 ; i < vector.count() ; ++i ) {
+ CacheHTTPInfo* info = vector.get(i);
+ if (info && info->m_alt) alt_length += info->m_alt->m_unmarshal_len;
+ }
+ Note("OpenReadHead failed for cachekey %X : vector inconsistency - "
+ "unmarshalled %d expecting %d in %d (base=%d, flen=%d) "
+ "- vector n=%d size=%d"
+ "first alt=%d[%s]"
+ , key.word(0)
+ , uml, doc->hlen, doc->len, sizeofDoc, doc->_flen
+ , vector.count(), alt_length
+ , alt->m_magic
+ , (CACHE_ALT_MAGIC_ALIVE == alt->m_magic ? "alive"
+ : CACHE_ALT_MAGIC_MARSHALED == alt->m_magic ? "serial"
+ : CACHE_ALT_MAGIC_DEAD == alt->m_magic ? "dead"
+ : "bogus")
+ );
dir_delete(&key, vol, &dir);
}
err = ECACHE_BAD_META_DATA;
View
51 proxy/hdrs/HTTP.cc
@@ -1520,28 +1520,30 @@ class UrlPrintHack {
URLImpl* ui = hdr->m_url_cached.m_url_impl;
char port_buff[10];
- // Save values that can be modified.
- m_hdr = hdr; // mark as having saved values.
- m_len_host = ui->m_len_host;
- m_ptr_host = ui->m_ptr_host;
- m_len_port = ui->m_len_port;
- m_ptr_port = ui->m_ptr_port;
+ m_hdr = hdr; // mark as potentially having modified values.
/* Get dirty. We reach in to the URL implementation to
set the host and port if
- 1) They are not already set and
- 2) The values were in a HTTP header field.
+ 1) They are not already set
+ AND
+ 2) The values were in a HTTP header.
*/
if (!hdr->m_target_in_url && hdr->m_host_length && hdr->m_host_mime) {
- assert(0 == ui->m_ptr_host); // shouldn't be non-zero if not in URL.
+ ink_assert(0 == ui->m_ptr_host); // shouldn't be non-zero if not in URL.
ui->m_ptr_host = hdr->m_host_mime->m_ptr_value;
ui->m_len_host = hdr->m_host_length;
+ m_host_modified_p = true;
+ } else {
+ m_host_modified_p = false;
}
if (0 == hdr->m_url_cached.port_get_raw() && hdr->m_port_in_header) {
- assert(0 == ui->m_ptr_port); // shouldn't be set if not in URL.
+ ink_assert(0 == ui->m_ptr_port); // shouldn't be set if not in URL.
ui->m_ptr_port = port_buff;
ui->m_len_port = sprintf(port_buff, "%.5d", hdr->m_port);
+ m_port_modified_p = true;
+ } else {
+ m_port_modified_p = false;
}
} else {
m_hdr = 0;
@@ -1549,14 +1551,23 @@ class UrlPrintHack {
}
/// Destructor.
- /// If we have a valid header, write the original URL values back.
~UrlPrintHack() {
- if (m_hdr) {
+ if (m_hdr) { // There was a potentially modified header.
URLImpl* ui = m_hdr->m_url_cached.m_url_impl;
- ui->m_len_port = m_len_port;
- ui->m_len_host = m_len_host;
- ui->m_ptr_port = m_ptr_port;
- ui->m_ptr_host = m_ptr_host;
+ // Because we only modified if not set, we can just set these values
+ // back to zero if modified. We want to be careful because if a
+ // heap re-allocation happened while this was active, then a saved value
+ // is wrong and will break things if restored. We don't have to worry
+ // about these because, if modified, they were originally NULL and should
+ // still be NULL after a re-allocate.
+ if (m_port_modified_p) {
+ ui->m_len_port = 0;
+ ui->m_ptr_port = 0;
+ }
+ if (m_host_modified_p) {
+ ui->m_len_host = 0;
+ ui->m_ptr_host = 0;
+ }
}
}
@@ -1567,10 +1578,8 @@ class UrlPrintHack {
/// Saved values.
///@{
- char const* m_ptr_host;
- char const* m_ptr_port;
- int m_len_host;
- int m_len_port;
+ bool m_host_modified_p;
+ bool m_port_modified_p;
HTTPHdr* m_hdr;
///@}
};
@@ -1862,7 +1871,7 @@ HTTPInfo::marshal(char *buf, int len)
buf += HTTP_ALT_MARSHAL_SIZE;
used += HTTP_ALT_MARSHAL_SIZE;
- if (frag_len) {
+ if (frag_len > 0) {
marshal_alt->m_frag_offsets = static_cast<FragOffset*>(reinterpret_cast<void*>(used));
memcpy(buf, m_alt->m_frag_offsets + HTTPCacheAlt::N_INTEGRAL_FRAG_OFFSETS, frag_len);
buf += frag_len;
Please sign in to comment.
Something went wrong with that request. Please try again.