1bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov/* Copyright (c) 2008-2010, Google Inc. 2bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * All rights reserved. 3bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * 4bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * Redistribution and use in source and binary forms, with or without 5bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * modification, are permitted provided that the following conditions are 6bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * met: 7bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * 8bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * * Redistributions of source code must retain the above copyright 9bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * notice, this list of conditions and the following disclaimer. 10bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * * Neither the name of Google Inc. nor the names of its 11bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * contributors may be used to endorse or promote products derived from 12bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * this software without specific prior written permission. 13bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * 14bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov */ 26bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 27bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// This file is part of ThreadSanitizer, a dynamic data race detector. 28bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Author: Evgeniy Stepanov. 29bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 30bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// This file contains the parser for valgrind-compatible suppressions. 31bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 32bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#include "suppressions.h" 33bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 34bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// TODO(eugenis): convert checks to warning messages. 35bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// TODO(eugenis): write tests for incorrect syntax. 36bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 37bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovenum LocationType { 38bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov LT_STAR, // ... 39bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov LT_OBJ, // obj: 40bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov LT_FUN, // fun: 41bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}; 42bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 43bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct Location { 44bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov LocationType type; 45bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string name; 46bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}; 47bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 48bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct StackTraceTemplate { 49bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov vector<Location> locations; 50bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}; 51bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 52bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct Suppression { 53bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string name; 54bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov set<string> tools; 55bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string warning_name; 56bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // Extra information available for some suppression types. 57bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // ex.: Memcheck:Param 58bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string extra; 59bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov vector<StackTraceTemplate> templates; 60bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}; 61bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 62bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovclass Parser { 63bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov public: 64bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov explicit Parser(const string &str) 65bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov : buffer_(str), next_(buffer_.c_str()), 66bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov end_(buffer_.c_str() + buffer_.size()), line_no_(0), error_(false) {} 67bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 68bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool NextSuppression(Suppression* suppression); 69bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool GetError(); 70bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string GetErrorString(); 71bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov int GetLineNo(); 72bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 73bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov private: 74bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool Eof() { return next_ >= end_; } 75bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string NextLine(); 76bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string NextLineSkipComments(); 77bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov void PutBackSkipComments(string line); 78bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool ParseSuppressionToolsLine(Suppression* supp, string line); 79bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool IsExtraLine(string line); 80bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool ParseStackTraceLine(StackTraceTemplate* trace, string line); 81bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool NextStackTraceTemplate(StackTraceTemplate* trace, bool* last); 82bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 83bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov void SetError(string desc); 84bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 85bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const string& buffer_; 86bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const char* next_; 87bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const char* end_; 88bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov stack<string> put_back_stack_; 89bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 90bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov int line_no_; 91bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool error_; 92bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string error_string_; 93bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}; 94bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 95bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#define PARSER_CHECK(cond, desc) do {\ 96bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (!(cond)) {\ 97bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov SetError(desc);\ 98bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false;\ 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }} while ((void)0, 0) 100bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 101bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovvoid Parser::SetError(string desc) { 102bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov error_ = true; 103bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov error_string_ = desc; 104bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 105bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 106bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool Parser::GetError() { 107bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return error_; 108bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 109bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 110bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstring Parser::GetErrorString() { 111bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return error_string_; 112bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 113bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 114bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovint Parser::GetLineNo() { 115bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return line_no_; 116bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 117bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 118bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstring Parser::NextLine() { 119bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const char* first = next_; 120bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (!Eof() && *next_ != '\n') { 121bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ++next_; 122bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 123bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string line(first, next_ - first); 124bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (*next_ == '\n') { 125bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ++next_; 126bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 127bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ++line_no_; 128bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return line; 129bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 130bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 131bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstring Parser::NextLineSkipComments() { 132bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string line; 133bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (!put_back_stack_.empty()) { 134bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = put_back_stack_.top(); 135bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov put_back_stack_.pop(); 136bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return line; 137bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 138bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (!Eof()) { 139bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = NextLine(); 140bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // Skip empty lines. 141bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line.empty()) 142bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov continue; 143bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // Skip comments. 144bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line[0] == '#') 145bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov continue; 146bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const char* p = line.c_str(); 147bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const char* e = p + line.size(); 148bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // Strip whitespace. 149bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (p < e && (*p == ' ' || *p == '\t')) 150bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ++p; 151bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (p >= e) 152bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov continue; 153bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const char* last = e - 1; 154bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (last > p && (*last == ' ' || *last == '\t')) 155bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov --last; 156bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return string(p, last - p + 1); 157bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 158bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return ""; 159bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 160bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 161bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovvoid Parser::PutBackSkipComments(string line) { 162bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov put_back_stack_.push(line); 163bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 164bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 165bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool Parser::ParseSuppressionToolsLine(Suppression* supp, string line) { 166bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov size_t idx = line.find(':'); 167bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PARSER_CHECK(idx != string::npos, "expected ':' in tools line"); 168bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string s1 = line.substr(0, idx); 169bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string s2 = line.substr(idx + 1); 170bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PARSER_CHECK(!s1.empty(), "expected non-empty tool(s) name"); 171bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PARSER_CHECK(!s2.empty(), "expected non-empty warning name"); 172bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov size_t idx2; 173bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while ((idx2 = s1.find(',')) != string::npos) { 174bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov supp->tools.insert(s1.substr(0, idx2)); 175bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov s1.erase(0, idx2 + 1); 176bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 177bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov supp->tools.insert(s1); 178bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov supp->warning_name = s2; 179bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 180bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 181bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 182bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool Parser::ParseStackTraceLine(StackTraceTemplate* trace, string line) { 183bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line == "...") { 184bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov Location location = {LT_STAR, ""}; 185bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov trace->locations.push_back(location); 186bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 187bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } else { 188bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov size_t idx = line.find(':'); 189bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PARSER_CHECK(idx != string::npos, "expected ':' in stack trace line"); 190bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string s1 = line.substr(0, idx); 191bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string s2 = line.substr(idx + 1); 192bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (s1 == "obj") { 193bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov Location location = {LT_OBJ, s2}; 194bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov trace->locations.push_back(location); 195bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 196bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } else if (s1 == "fun") { 197bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov Location location = {LT_FUN, s2}; 198db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov // A suppression frame can only have ( or ) if it comes from Objective-C, 199db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov // i.e. starts with +[ or -[ or =[ 200db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov PARSER_CHECK(s2.find_first_of("()") == string::npos || 201db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov (s2[1] == '[' && strchr("+-=", s2[0]) != NULL), 202db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov "'fun:' lines can't contain '()'"); 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // Check that we don't have template arguments in the suppression. 205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // Caveat: don't be confused by "operator>>" and similar... 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov size_t checked_till = 0; 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // List of possible >>-like operators, sorted by the operation length. 209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const char *OP[] = {">>=", "<<=", 210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ">>", "<<", 211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ">=", "<=", 212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "->", "->*", 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "<", ">"}; 214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov bool check_failed = false; 215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (!check_failed && checked_till < s2.size()) { 216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov size_t next = s2.find_first_of("<>", checked_till); 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (next == string::npos) 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (next < 8) { 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // operatorX won't fit 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov check_failed = true; 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (size_t i = 0; i < TS_ARRAY_SIZE(OP); i++) { 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov size_t op_offset = ((string)OP[i]).find(s2[next]); 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (op_offset == string::npos) 229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov continue; 230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (next >= 8 + op_offset && 231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "operator" == s2.substr(next- (8 + op_offset), 8) && 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov OP[i] == s2.substr(next- op_offset, strlen(OP[i]))) { 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov checked_till = next + strlen(OP[i] + op_offset); 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PARSER_CHECK(!check_failed, "'fun:' lines can't contain '<' or '>' " 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "except for operators"); 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 243bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov trace->locations.push_back(location); 244bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 245bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } else { 246bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov SetError("bad stack trace line"); 247bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 248bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 249bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 250bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 251bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 252bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Checks if this line can not be parsed by Parser::NextStackTraceTemplate 253bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// and, therefore, is an extra information for the suppression. 254bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool Parser::IsExtraLine(string line) { 255bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line == "..." || line == "{" || line == "}") 256bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 257bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line.size() < 4) 258bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 259bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string prefix = line.substr(0, 4); 260bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return !(prefix == "obj:" || prefix == "fun:"); 261bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 262bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 263bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool Parser::NextStackTraceTemplate(StackTraceTemplate* trace, 264bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool* last_stack_trace) { 265bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string line = NextLineSkipComments(); 266bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line == "}") { // No more stack traces in multi-trace syntax 267bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *last_stack_trace = true; 268bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 269bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 270bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 271bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line == "{") { // A multi-trace syntax 272bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = NextLineSkipComments(); 273bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } else { 274bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *last_stack_trace = true; 275bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 276bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 277bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (true) { 278bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (!ParseStackTraceLine(trace, line)) 279bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 280bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = NextLineSkipComments(); 281bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line == "}") 282bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov break; 283bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 284bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 285bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 286bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 287bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool Parser::NextSuppression(Suppression* supp) { 288bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string line; 289bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = NextLineSkipComments(); 290bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (line.empty()) 291bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 292bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // Opening { 293bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PARSER_CHECK(line == "{", "expected '{'"); 294bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // Suppression name. 295bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = NextLineSkipComments(); 296bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PARSER_CHECK(!line.empty(), "expected suppression name"); 297bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov supp->name = line; 298bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // tool[,tool]:warning_name. 299bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = NextLineSkipComments(); 300bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PARSER_CHECK(!line.empty(), "expected tool[, tool]:warning_name line"); 301bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (!ParseSuppressionToolsLine(supp, line)) 302bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 303bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (0) { // Not used currently. May still be needed later. 304bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // A possible extra line. 305bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov line = NextLineSkipComments(); 306bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (IsExtraLine(line)) 307bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov supp->extra = line; 308bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov else 309bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov PutBackSkipComments(line); 310bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 311bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // Everything else. 312bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool done = false; 313bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (!done) { 314bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov StackTraceTemplate trace; 315bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (NextStackTraceTemplate(&trace, &done)) 316bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov supp->templates.push_back(trace); 317bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (error_) 318bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 319bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 320bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov // TODO(eugenis): Do we need to check for empty traces? 321bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 322bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 323bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 324bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct Suppressions::SuppressionsRep { 325bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov vector<Suppression> suppressions; 326bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string error_string_; 327bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov int error_line_no_; 328bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}; 329bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 330bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy StepanovSuppressions::Suppressions() : rep_(new SuppressionsRep) {} 331bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 332bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy StepanovSuppressions::~Suppressions() { 333bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov delete rep_; 334bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 335bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 336bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovint Suppressions::ReadFromString(const string &str) { 337bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov int sizeBefore = rep_->suppressions.size(); 338bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov Parser parser(str); 339bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov Suppression supp; 340bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (parser.NextSuppression(&supp)) { 341bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov rep_->suppressions.push_back(supp); 342bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 343bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (parser.GetError()) { 344bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov rep_->error_string_ = parser.GetErrorString(); 345bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov rep_->error_line_no_ = parser.GetLineNo(); 346bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return -1; 347bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 348bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return rep_->suppressions.size() - sizeBefore; 349bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 350bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 351bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstring Suppressions::GetErrorString() { 352bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return rep_->error_string_; 353bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 354bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 355bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovint Suppressions::GetErrorLineNo() { 356bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return rep_->error_line_no_; 357bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 358bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 359bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct MatcherContext { 360bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov MatcherContext( 361bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& function_names_mangled_, 362bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& function_names_demangled_, 363bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& object_names_) : 364bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov function_names_mangled(function_names_mangled_), 365bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov function_names_demangled(function_names_demangled_), 366bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov object_names(object_names_), 367bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov tmpl(NULL) 368bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov {} 369bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 370bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& function_names_mangled; 371bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& function_names_demangled; 372bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& object_names; 373bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov StackTraceTemplate* tmpl; 374bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}; 375bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 376bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstatic bool MatchStackTraceRecursive(MatcherContext ctx, int trace_index, 377bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov int tmpl_index) { 378bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const int trace_size = ctx.function_names_mangled.size(); 379bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const int tmpl_size = ctx.tmpl->locations.size(); 380bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (trace_index < trace_size && tmpl_index < tmpl_size) { 381bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov Location& location = ctx.tmpl->locations[tmpl_index]; 382bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (location.type == LT_STAR) { 383bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ++tmpl_index; 384bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov while (trace_index < trace_size) { 385bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (MatchStackTraceRecursive(ctx, trace_index++, tmpl_index)) 386bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 387bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 388bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 389bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } else { 390bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool match = false; 391bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (location.type == LT_OBJ) { 392bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov match = StringMatch(location.name, ctx.object_names[trace_index]); 393bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } else { 394bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov CHECK(location.type == LT_FUN); 395bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov match = 396bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov StringMatch(location.name, ctx.function_names_mangled[trace_index]) || 397bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov StringMatch(location.name, ctx.function_names_demangled[trace_index]); 398bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 399bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (match) { 400bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ++trace_index; 401bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ++tmpl_index; 402bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } else { 403bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 404bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 405bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 406bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 407bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return tmpl_index == tmpl_size; 408bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 409bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov 410bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool Suppressions::StackTraceSuppressed(string tool_name, string warning_name, 411bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& function_names_mangled, 412bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& function_names_demangled, 413bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov const vector<string>& object_names, 414bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov string *name_of_suppression) { 415bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov MatcherContext ctx(function_names_mangled, function_names_demangled, 416bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov object_names); 417bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov for (vector<Suppression>::iterator it = rep_->suppressions.begin(); 418bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov it != rep_->suppressions.end(); ++it) { 419bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (it->warning_name != warning_name || 420bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov it->tools.find(tool_name) == it->tools.end()) 421bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov continue; 422bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov for (vector<StackTraceTemplate>::iterator it2 = it->templates.begin(); 423bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov it2 != it->templates.end(); ++it2) { 424bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov ctx.tmpl = &*it2; 425bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov bool result = MatchStackTraceRecursive(ctx, 0, 0); 426bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov if (result) { 427bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *name_of_suppression = it->name; 428bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return true; 429bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 430bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 431bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov } 432bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov return false; 433bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov} 434