diff options
author | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-07-07 20:53:52 +0000 |
---|---|---|
committer | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-07-07 20:53:52 +0000 |
commit | 69607b678fabd81ce7e77bd50cec0fa343e73b3e (patch) | |
tree | e176c234b585aa6e8ac336e85fce6671d5584637 /src/processor/network_source_line_server.cc | |
parent | Add some unit tests for Linux WriteSymbolFile (diff) | |
download | breakpad-69607b678fabd81ce7e77bd50cec0fa343e73b3e.tar.xz |
Remove NetworkSourceLine{Resolver,Server} and related code. It never wound up being useful enough to use in production, so let's drop the maintenence burden
R=jessicag at http://breakpad.appspot.com/292001/show
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@795 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/processor/network_source_line_server.cc')
-rw-r--r-- | src/processor/network_source_line_server.cc | 435 |
1 files changed, 0 insertions, 435 deletions
diff --git a/src/processor/network_source_line_server.cc b/src/processor/network_source_line_server.cc deleted file mode 100644 index 1a6ea31b..00000000 --- a/src/processor/network_source_line_server.cc +++ /dev/null @@ -1,435 +0,0 @@ -// Copyright (c) 2010, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include <arpa/inet.h> -#include <netinet/in.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/types.h> - -#include <algorithm> -#include <iostream> -#include <sstream> - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "google_breakpad/processor/code_module.h" -#include "google_breakpad/processor/stack_frame.h" -#include "processor/basic_code_module.h" -#include "processor/binarystream.h" -#include "processor/cfi_frame_info.h" -#include "processor/logging.h" -#include "processor/network_source_line_protocol.h" -#include "processor/network_source_line_server.h" -#include "processor/tokenize.h" -#include "processor/windows_frame_info.h" - -namespace google_breakpad { - -using std::dec; -using std::find; -using std::hex; -// Style guide forbids "using namespace", so at least shorten it. -namespace P = source_line_protocol; - -bool NetworkSourceLineServer::Initialize() { - if (net_->Init(true)) - initialized_ = true; - return initialized_; -} - -bool NetworkSourceLineServer::RunForever() { - if (!initialized_ && !Initialize()) - return false; - - BPLOG(INFO) << "Running forever..."; - while (true) { - RunOnce(5000); - } - // not reached - return true; -} - -bool NetworkSourceLineServer::RunOnce(int wait_milliseconds) { - if (!initialized_ && !Initialize()) - return false; - - if (!net_->WaitToReceive(wait_milliseconds)) - return false; - //TODO(ted): loop, processing packets until wait_milliseconds - // is actually exhausted? - - vector<char> buffer(1024); - ssize_t received_bytes; - if (!net_->Receive(&buffer[0], buffer.size(), received_bytes)) - return false; - buffer.resize(received_bytes); - - binarystream request(&buffer[0], buffer.size()); - binarystream response; - if (!HandleRequest(request, response)) - return false; - - string response_string = response.str(); - if (!net_->Send(response_string.c_str(), response_string.length())) - return false; - return true; -} - -bool NetworkSourceLineServer::HandleRequest(binarystream &request, - binarystream &response) { - u_int16_t sequence_number; - u_int8_t command; - request >> sequence_number >> command; - if (request.eof()) { - BPLOG(ERROR) << "Malformed request, missing sequence number or command"; - return false; - } - - response.rewind(); - response << sequence_number; - switch(command) { - case P::HAS: - HandleHas(request, response); - break; - case P::LOAD: - HandleLoad(request, response); - break; - case P::GET: - HandleGet(request, response); - break; - case P::GETSTACKWIN: - HandleGetStackWin(request, response); - break; - case P::GETSTACKCFI: - HandleGetStackCFI(request, response); - break; - default: - BPLOG(ERROR) << "Unknown command " << int(command); - response << P::ERROR; - break; - } - return true; -} - -void NetworkSourceLineServer::HandleHas(binarystream &message, - binarystream &response) { - string module_name, debug_file, debug_id; - message >> module_name >> debug_file >> debug_id; - if (message.eof()) { - BPLOG(ERROR) << "HAS message malformed"; - response << P::ERROR; - return; - } - BPLOG(INFO) << "Received message HAS " << module_name - << " " << debug_file - << " " << debug_id; - // Need to lie about the module name here, since BasicSourceLineResolver - // uses only the module name for unique modules, but we want to allow - // multiple versions of the same named module in here. - BasicCodeModule module((u_int64_t)0, (u_int64_t)0, - module_name + "|" + debug_file + "|" + debug_id, "", - debug_file, debug_id, ""); - u_int8_t data; - if (resolver_) { - data = resolver_->HasModule(&module) - ? P::MODULE_LOADED : P::MODULE_NOT_LOADED; - } else { - data = P::MODULE_NOT_LOADED; - } - response << P::OK << data; -} - -void NetworkSourceLineServer::HandleLoad(binarystream &message, - binarystream &response) { - string module_name, debug_file, debug_id; - message >> module_name >> debug_file >> debug_id; - if (message.eof()) { - BPLOG(ERROR) << "LOAD message malformed"; - response << P::ERROR; - return; - } - BPLOG(INFO) << "Received message LOAD " << module_name - << " " << debug_file - << " " << debug_id; - - u_int8_t reply; - // stub out the bare minimum here - BasicCodeModule module((u_int64_t)0, (u_int64_t)0, - module_name + "|" + debug_file + "|" + debug_id, "", - debug_file, debug_id, ""); - if (resolver_->HasModule(&module)) { - // just short-circuit the rest of this, since it's already loaded - BPLOG(INFO) << "Got LOAD for already loaded " << module_name; - UsedModule(module); - reply = P::LOAD_OK; - } else { - BPLOG(INFO) << "Looking up symbols for (" << module_name << ", " - << debug_file << ", " << debug_id << ")"; - string symbol_data, symbol_file; - SymbolSupplier::SymbolResult symbol_result; - if (supplier_) { - symbol_result = supplier_->GetSymbolFile(&module, NULL, - &symbol_file, &symbol_data); - } else { - symbol_result = SymbolSupplier::NOT_FOUND; - } - - switch (symbol_result) { - case SymbolSupplier::FOUND: { - BPLOG(INFO) << "Found symbols for " << module_name; - reply = P::LOAD_OK; - // also go ahead and load the symbols while we're here, - // since the client is just going to ask us to do this right away - // and we already have |symbol_data| here. - int numlines = CountNewlines(symbol_data); - if (!resolver_->LoadModuleUsingMapBuffer(&module, - symbol_data)) { - BPLOG(INFO) << "Failed to load symbols for " << module_name; - reply = P::LOAD_FAIL; - } else { - // save some info about this module - symbol_lines_ += numlines; - UsedModule(module); - module_symbol_lines_[module.code_file()] = numlines; - - BPLOG(INFO) << "Loaded symbols for " << module_name - << " (" << dec << numlines << " lines, " - << symbol_lines_ << " total)"; - - if (max_symbol_lines_ != 0 && symbol_lines_ > max_symbol_lines_) { - // try unloading some modules to reclaim memory - // (but not the one that was just loaded) - BPLOG(INFO) << "Exceeded limit of " << dec << max_symbol_lines_ - << " symbol lines loaded, trying to unload modules"; - TryUnloadModules(module); - } - } - } - break; - case SymbolSupplier::NOT_FOUND: - BPLOG(INFO) << "Symbols not found for " << module_name; - reply = P::LOAD_NOT_FOUND; - break; - case SymbolSupplier::INTERRUPT: - BPLOG(INFO) << "Symbol provider returned interrupt for " << module_name; - reply = P::LOAD_INTERRUPT; - break; - } - } - response << P::OK << reply; -} - -void NetworkSourceLineServer::HandleGet(binarystream &message, - binarystream &response) { - string module_name, debug_file, debug_id; - u_int64_t module_base, instruction; - message >> module_name >> debug_file >> debug_id - >> module_base >> instruction; - if (message.eof()) { - BPLOG(ERROR) << "GET message malformed"; - response << P::ERROR; - return; - } - - BPLOG(INFO) << "Received message GET " << module_name << " " - << debug_file << " " << debug_id << " " - << hex << module_base << " " << instruction; - - StackFrame frame; - if (resolver_) { - BasicCodeModule module(module_base, (u_int64_t)0, - module_name + "|" + debug_file + "|" + debug_id, "", - debug_file, debug_id, ""); - frame.module = &module; - frame.instruction = instruction; - resolver_->FillSourceLineInfo(&frame); - UsedModule(module); - } - - response << P::OK << frame.function_name << frame.function_base - << frame.source_file_name << u_int32_t(frame.source_line) - << frame.source_line_base; - BPLOG(INFO) << "Sending GET response: " << frame.function_name << " " - << hex << frame.function_base << " " - << frame.source_file_name << " " - << dec << frame.source_line << " " - << hex << frame.source_line_base; -} - -void NetworkSourceLineServer::HandleGetStackWin(binarystream &message, - binarystream &response) { - string module_name, debug_file, debug_id; - u_int64_t module_base, instruction; - message >> module_name >> debug_file >> debug_id - >> module_base >> instruction; - if (message.eof()) { - BPLOG(ERROR) << "GETSTACKWIN message malformed"; - response << P::ERROR; - return; - } - - BPLOG(INFO) << "Received message GETSTACKWIN " << module_name << " " - << debug_file << " " << debug_id << " " - << hex << module_base << " " << instruction; - - - WindowsFrameInfo *frame_info = NULL; - if (resolver_) { - StackFrame frame; - BasicCodeModule module(module_base, (u_int64_t)0, - module_name + "|" + debug_file + "|" + debug_id, "", - debug_file, debug_id, ""); - frame.module = &module; - frame.instruction = instruction; - frame_info = resolver_->FindWindowsFrameInfo(&frame); - UsedModule(module); - } - - response << P::OK << FormatWindowsFrameInfo(frame_info); - BPLOG(INFO) << "Sending GETSTACKWIN response: " - << FormatWindowsFrameInfo(frame_info); - delete frame_info; -} - -string NetworkSourceLineServer::FormatWindowsFrameInfo( - WindowsFrameInfo *frame_info) { - if (frame_info == NULL) - return ""; - - std::ostringstream stream; - // Put "0" as the type, rva and code size because the client doesn't - // actually care what these values are, but it's easier to keep the - // format consistent with the symbol files so the parsing code can be - // shared. - stream << "0 0 0 " << hex - << frame_info->prolog_size << " " - << frame_info->epilog_size << " " - << frame_info->parameter_size << " " - << frame_info->saved_register_size << " " - << frame_info->local_size << " " - << frame_info->max_stack_size << " "; - if (!frame_info->program_string.empty()) { - stream << 1 << " " << frame_info->program_string; - } else { - stream << 0 << " " << frame_info->allocates_base_pointer; - } - return stream.str(); -} - -void NetworkSourceLineServer::HandleGetStackCFI(binarystream &message, - binarystream &response) { - string module_name, debug_file, debug_id; - u_int64_t module_base, instruction; - message >> module_name >> debug_file >> debug_id - >> module_base >> instruction; - if (message.eof()) { - BPLOG(ERROR) << "GETSTACKCFI message malformed"; - response << P::ERROR; - return; - } - - BPLOG(INFO) << "Received message GETSTACKCFI " << module_name << " " - << debug_file << " " << debug_id << " " - << hex << module_base << " " << instruction; - - - CFIFrameInfo *frame_info = NULL; - if (resolver_) { - StackFrame frame; - BasicCodeModule module(module_base, (u_int64_t)0, - module_name + "|" + debug_file + "|" + debug_id, "", - debug_file, debug_id, ""); - frame.module = &module; - frame.instruction = instruction; - frame_info = resolver_->FindCFIFrameInfo(&frame); - UsedModule(module); - } - - string frame_info_string; - if (frame_info != NULL) - frame_info_string = frame_info->Serialize(); - response << P::OK << frame_info_string; - BPLOG(INFO) << "Sending GETSTACKCFI response: " - << frame_info_string; - delete frame_info; -} - -int NetworkSourceLineServer::CountNewlines(const string &str) { - int count = 0; - string::const_iterator iter = str.begin(); - while (iter != str.end()) { - if (*iter == '\n') - count++; - iter++; - } - return count; -} - -void NetworkSourceLineServer::UsedModule(const CodeModule &module) { - list<string>::iterator iter = find(modules_used_.begin(), - modules_used_.end(), - module.code_file()); - if (iter == modules_used_.end()) { - modules_used_.push_front(module.code_file()); - } else { - modules_used_.splice(modules_used_.begin(), - modules_used_, - iter); - } -} - -void NetworkSourceLineServer::TryUnloadModules( - const CodeModule &just_loaded_module) { - if (!resolver_) - return; - - while (symbol_lines_ > max_symbol_lines_) { - // never unload just_loaded_module - if (modules_used_.back() == just_loaded_module.code_file()) - break; - - string module_to_unload = modules_used_.back(); - modules_used_.pop_back(); - BasicCodeModule module(0, 0, module_to_unload, "", "", "", ""); - BPLOG(INFO) << "Unloading module " << module_to_unload; - resolver_->UnloadModule(&module); - - // reduce the symbol line count - map<string, int>::iterator iter = - module_symbol_lines_.find(module_to_unload); - if (iter != module_symbol_lines_.end()) { - symbol_lines_ -= iter->second; - module_symbol_lines_.erase(iter); - } - } -} - -} // namespace google_breakpad |