LCOV - code coverage report
Current view: top level - src - log-utils.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 55 113 48.7 %
Date: 2017-04-26 Functions: 10 17 58.8 %

          Line data    Source code
       1             : // Copyright 2009 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/log-utils.h"
       6             : 
       7             : #include "src/assert-scope.h"
       8             : #include "src/base/platform/platform.h"
       9             : #include "src/objects-inl.h"
      10             : #include "src/string-stream.h"
      11             : #include "src/utils.h"
      12             : #include "src/version.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : 
      18             : const char* const Log::kLogToTemporaryFile = "&";
      19             : const char* const Log::kLogToConsole = "-";
      20             : 
      21             : 
      22       60782 : Log::Log(Logger* logger)
      23             :   : is_stopped_(false),
      24             :     output_handle_(NULL),
      25             :     message_buffer_(NULL),
      26       60782 :     logger_(logger) {
      27       60782 : }
      28             : 
      29             : 
      30       60782 : void Log::Initialize(const char* log_file_name) {
      31       60782 :   message_buffer_ = NewArray<char>(kMessageBufferSize);
      32             : 
      33             :   // --log-all enables all the log flags.
      34       60782 :   if (FLAG_log_all) {
      35           0 :     FLAG_log_api = true;
      36           0 :     FLAG_log_code = true;
      37           0 :     FLAG_log_gc = true;
      38           0 :     FLAG_log_suspect = true;
      39           0 :     FLAG_log_handles = true;
      40           0 :     FLAG_log_internal_timer_events = true;
      41             :   }
      42             : 
      43             :   // --prof implies --log-code.
      44       60782 :   if (FLAG_prof) FLAG_log_code = true;
      45             : 
      46             :   // If we're logging anything, we need to open the log file.
      47       60782 :   if (Log::InitLogAtStart()) {
      48          24 :     if (strcmp(log_file_name, kLogToConsole) == 0) {
      49             :       OpenStdout();
      50          24 :     } else if (strcmp(log_file_name, kLogToTemporaryFile) == 0) {
      51             :       OpenTemporaryFile();
      52             :     } else {
      53             :       OpenFile(log_file_name);
      54             :     }
      55             : 
      56          24 :     if (output_handle_ != nullptr) {
      57             :       Log::MessageBuilder msg(this);
      58             :       msg.Append("v8-version,%d,%d,%d,%d,%d", Version::GetMajor(),
      59             :                  Version::GetMinor(), Version::GetBuild(), Version::GetPatch(),
      60          48 :                  Version::IsCandidate());
      61          24 :       msg.WriteToLogFile();
      62             :     }
      63             :   }
      64       60782 : }
      65             : 
      66             : 
      67           0 : void Log::OpenStdout() {
      68             :   DCHECK(!IsEnabled());
      69           0 :   output_handle_ = stdout;
      70           0 : }
      71             : 
      72             : 
      73           0 : void Log::OpenTemporaryFile() {
      74             :   DCHECK(!IsEnabled());
      75          24 :   output_handle_ = base::OS::OpenTemporaryFile();
      76           0 : }
      77             : 
      78             : 
      79           0 : void Log::OpenFile(const char* name) {
      80             :   DCHECK(!IsEnabled());
      81           0 :   output_handle_ = base::OS::FOpen(name, base::OS::LogFileOpenMode);
      82           0 : }
      83             : 
      84             : 
      85       59285 : FILE* Log::Close() {
      86             :   FILE* result = NULL;
      87       59285 :   if (output_handle_ != NULL) {
      88          24 :     if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
      89           0 :       fclose(output_handle_);
      90             :     } else {
      91             :       result = output_handle_;
      92             :     }
      93             :   }
      94       59285 :   output_handle_ = NULL;
      95             : 
      96       59285 :   DeleteArray(message_buffer_);
      97       59285 :   message_buffer_ = NULL;
      98             : 
      99       59285 :   is_stopped_ = false;
     100       59285 :   return result;
     101             : }
     102             : 
     103             : 
     104       50019 : Log::MessageBuilder::MessageBuilder(Log* log)
     105             :   : log_(log),
     106             :     lock_guard_(&log_->mutex_),
     107      100086 :     pos_(0) {
     108             :   DCHECK(log_->message_buffer_ != NULL);
     109       50019 : }
     110             : 
     111             : 
     112      246608 : void Log::MessageBuilder::Append(const char* format, ...) {
     113             :   Vector<char> buf(log_->message_buffer_ + pos_,
     114             :                    Log::kMessageBufferSize - pos_);
     115             :   va_list args;
     116      246608 :   va_start(args, format);
     117      246608 :   AppendVA(format, args);
     118      246608 :   va_end(args);
     119             :   DCHECK(pos_ <= Log::kMessageBufferSize);
     120      246608 : }
     121             : 
     122             : 
     123      246608 : void Log::MessageBuilder::AppendVA(const char* format, va_list args) {
     124             :   Vector<char> buf(log_->message_buffer_ + pos_,
     125      246608 :                    Log::kMessageBufferSize - pos_);
     126      246608 :   int result = v8::internal::VSNPrintF(buf, format, args);
     127             : 
     128             :   // Result is -1 if output was truncated.
     129      246608 :   if (result >= 0) {
     130      246608 :     pos_ += result;
     131             :   } else {
     132           0 :     pos_ = Log::kMessageBufferSize;
     133             :   }
     134             :   DCHECK(pos_ <= Log::kMessageBufferSize);
     135      246608 : }
     136             : 
     137             : 
     138       15732 : void Log::MessageBuilder::Append(const char c) {
     139      720182 :   if (pos_ < Log::kMessageBufferSize) {
     140      720182 :     log_->message_buffer_[pos_++] = c;
     141             :   }
     142             :   DCHECK(pos_ <= Log::kMessageBufferSize);
     143       15732 : }
     144             : 
     145             : 
     146       32939 : void Log::MessageBuilder::AppendDoubleQuotedString(const char* string) {
     147             :   Append('"');
     148      671511 :   for (const char* p = string; *p != '\0'; p++) {
     149      638572 :     if (*p == '"') {
     150             :       Append('\\');
     151             :     }
     152      638572 :     Append(*p);
     153             :   }
     154             :   Append('"');
     155       32939 : }
     156             : 
     157             : 
     158           0 : void Log::MessageBuilder::Append(String* str) {
     159             :   DisallowHeapAllocation no_gc;  // Ensure string stay valid.
     160             :   int length = str->length();
     161           0 :   for (int i = 0; i < length; i++) {
     162           0 :     Append(static_cast<char>(str->Get(i)));
     163             :   }
     164           0 : }
     165             : 
     166       65467 : void Log::MessageBuilder::AppendAddress(Address addr) {
     167       65467 :   Append("%p", static_cast<void*>(addr));
     168       65467 : }
     169             : 
     170           0 : void Log::MessageBuilder::AppendSymbolName(Symbol* symbol) {
     171             :   DCHECK(symbol);
     172           0 :   Append("symbol(");
     173           0 :   if (!symbol->name()->IsUndefined(symbol->GetIsolate())) {
     174           0 :     Append("\"");
     175           0 :     AppendDetailed(String::cast(symbol->name()), false);
     176           0 :     Append("\" ");
     177             :   }
     178           0 :   Append("hash %x)", symbol->Hash());
     179           0 : }
     180             : 
     181             : 
     182           0 : void Log::MessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
     183           0 :   if (str == NULL) return;
     184             :   DisallowHeapAllocation no_gc;  // Ensure string stay valid.
     185             :   int len = str->length();
     186           0 :   if (len > 0x1000)
     187             :     len = 0x1000;
     188           0 :   if (show_impl_info) {
     189           0 :     Append(str->IsOneByteRepresentation() ? 'a' : '2');
     190           0 :     if (StringShape(str).IsExternal())
     191             :       Append('e');
     192           0 :     if (StringShape(str).IsInternalized())
     193             :       Append('#');
     194           0 :     Append(":%i:", str->length());
     195             :   }
     196           0 :   for (int i = 0; i < len; i++) {
     197           0 :     uc32 c = str->Get(i);
     198           0 :     if (c > 0xff) {
     199           0 :       Append("\\u%04x", c);
     200           0 :     } else if (c < 32 || c > 126) {
     201           0 :       Append("\\x%02x", c);
     202           0 :     } else if (c == ',') {
     203           0 :       Append("\\,");
     204           0 :     } else if (c == '\\') {
     205           0 :       Append("\\\\");
     206           0 :     } else if (c == '\"') {
     207           0 :       Append("\"\"");
     208             :     } else {
     209           0 :       Append("%lc", c);
     210             :     }
     211             :   }
     212             : }
     213             : 
     214             : 
     215           0 : void Log::MessageBuilder::AppendStringPart(const char* str, int len) {
     216           0 :   if (pos_ + len > Log::kMessageBufferSize) {
     217           0 :     len = Log::kMessageBufferSize - pos_;
     218             :     DCHECK(len >= 0);
     219           0 :     if (len == 0) return;
     220             :   }
     221             :   Vector<char> buf(log_->message_buffer_ + pos_,
     222           0 :                    Log::kMessageBufferSize - pos_);
     223           0 :   StrNCpy(buf, str, len);
     224           0 :   pos_ += len;
     225             :   DCHECK(pos_ <= Log::kMessageBufferSize);
     226             : }
     227             : 
     228             : 
     229       50043 : void Log::MessageBuilder::WriteToLogFile() {
     230             :   DCHECK(pos_ <= Log::kMessageBufferSize);
     231             :   // Assert that we do not already have a new line at the end.
     232             :   DCHECK(pos_ == 0 || log_->message_buffer_[pos_ - 1] != '\n');
     233       50043 :   if (pos_ == Log::kMessageBufferSize) pos_--;
     234       50043 :   log_->message_buffer_[pos_++] = '\n';
     235       50043 :   const int written = log_->WriteToFile(log_->message_buffer_, pos_);
     236       50043 :   if (written != pos_) {
     237           0 :     log_->stop();
     238           0 :     log_->logger_->LogFailure();
     239             :   }
     240       50043 : }
     241             : 
     242             : 
     243             : }  // namespace internal
     244             : }  // namespace v8

Generated by: LCOV version 1.10