blob: 22972ec0551bd700936332583423ef64779a152f [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2009 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/log-utils.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006
7#include "src/assert-scope.h"
8#include "src/base/platform/platform.h"
9#include "src/objects-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/string-stream.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/utils.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040012#include "src/version.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000013
14namespace v8 {
15namespace internal {
16
Steve Blocka7e24c12009-10-30 11:49:00 +000017
Ben Murdoch69a99ed2011-11-30 16:03:39 +000018const char* const Log::kLogToTemporaryFile = "&";
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019const char* const Log::kLogToConsole = "-";
Steve Blocka7e24c12009-10-30 11:49:00 +000020
21
Steve Block44f0eee2011-05-26 01:26:41 +010022Log::Log(Logger* logger)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000023 : is_stopped_(false),
Steve Block44f0eee2011-05-26 01:26:41 +010024 output_handle_(NULL),
Steve Block44f0eee2011-05-26 01:26:41 +010025 message_buffer_(NULL),
26 logger_(logger) {
27}
Steve Blocka7e24c12009-10-30 11:49:00 +000028
29
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030void Log::Initialize(const char* log_file_name) {
Steve Blocka7e24c12009-10-30 11:49:00 +000031 message_buffer_ = NewArray<char>(kMessageBufferSize);
Steve Block44f0eee2011-05-26 01:26:41 +010032
33 // --log-all enables all the log flags.
34 if (FLAG_log_all) {
Steve Block44f0eee2011-05-26 01:26:41 +010035 FLAG_log_api = true;
36 FLAG_log_code = true;
37 FLAG_log_gc = true;
38 FLAG_log_suspect = true;
39 FLAG_log_handles = true;
40 FLAG_log_regexp = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 FLAG_log_internal_timer_events = true;
Steve Block44f0eee2011-05-26 01:26:41 +010042 }
43
44 // --prof implies --log-code.
45 if (FLAG_prof) FLAG_log_code = true;
46
Steve Block44f0eee2011-05-26 01:26:41 +010047 // If we're logging anything, we need to open the log file.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 if (Log::InitLogAtStart()) {
49 if (strcmp(log_file_name, kLogToConsole) == 0) {
Steve Block44f0eee2011-05-26 01:26:41 +010050 OpenStdout();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051 } else if (strcmp(log_file_name, kLogToTemporaryFile) == 0) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000052 OpenTemporaryFile();
53 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054 OpenFile(log_file_name);
Steve Block44f0eee2011-05-26 01:26:41 +010055 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040056
57 if (output_handle_ != nullptr) {
58 Log::MessageBuilder msg(this);
59 msg.Append("v8-version,%d,%d,%d,%d,%d", Version::GetMajor(),
60 Version::GetMinor(), Version::GetBuild(), Version::GetPatch(),
61 Version::IsCandidate());
62 msg.WriteToLogFile();
63 }
Steve Block44f0eee2011-05-26 01:26:41 +010064 }
Steve Blocka7e24c12009-10-30 11:49:00 +000065}
66
67
68void Log::OpenStdout() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 DCHECK(!IsEnabled());
Steve Blocka7e24c12009-10-30 11:49:00 +000070 output_handle_ = stdout;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000071}
72
73
74void Log::OpenTemporaryFile() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 DCHECK(!IsEnabled());
76 output_handle_ = base::OS::OpenTemporaryFile();
Steve Blocka7e24c12009-10-30 11:49:00 +000077}
78
79
80void Log::OpenFile(const char* name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 DCHECK(!IsEnabled());
82 output_handle_ = base::OS::FOpen(name, base::OS::LogFileOpenMode);
Steve Blocka7e24c12009-10-30 11:49:00 +000083}
84
85
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000086FILE* Log::Close() {
87 FILE* result = NULL;
88 if (output_handle_ != NULL) {
89 if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
90 fclose(output_handle_);
91 } else {
92 result = output_handle_;
93 }
Steve Blocka7e24c12009-10-30 11:49:00 +000094 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000095 output_handle_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +000096
97 DeleteArray(message_buffer_);
98 message_buffer_ = NULL;
99
Steve Blocka7e24c12009-10-30 11:49:00 +0000100 is_stopped_ = false;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000101 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +0000102}
103
104
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105Log::MessageBuilder::MessageBuilder(Log* log)
106 : log_(log),
107 lock_guard_(&log_->mutex_),
Steve Block44f0eee2011-05-26 01:26:41 +0100108 pos_(0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109 DCHECK(log_->message_buffer_ != NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000110}
111
112
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113void Log::MessageBuilder::Append(const char* format, ...) {
Steve Block44f0eee2011-05-26 01:26:41 +0100114 Vector<char> buf(log_->message_buffer_ + pos_,
Steve Blocka7e24c12009-10-30 11:49:00 +0000115 Log::kMessageBufferSize - pos_);
116 va_list args;
117 va_start(args, format);
118 AppendVA(format, args);
119 va_end(args);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000121}
122
123
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124void Log::MessageBuilder::AppendVA(const char* format, va_list args) {
Steve Block44f0eee2011-05-26 01:26:41 +0100125 Vector<char> buf(log_->message_buffer_ + pos_,
Steve Blocka7e24c12009-10-30 11:49:00 +0000126 Log::kMessageBufferSize - pos_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 int result = v8::internal::VSNPrintF(buf, format, args);
Steve Blocka7e24c12009-10-30 11:49:00 +0000128
129 // Result is -1 if output was truncated.
130 if (result >= 0) {
131 pos_ += result;
132 } else {
133 pos_ = Log::kMessageBufferSize;
134 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000136}
137
138
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139void Log::MessageBuilder::Append(const char c) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000140 if (pos_ < Log::kMessageBufferSize) {
Steve Block44f0eee2011-05-26 01:26:41 +0100141 log_->message_buffer_[pos_++] = c;
Steve Blocka7e24c12009-10-30 11:49:00 +0000142 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000144}
145
146
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147void Log::MessageBuilder::AppendDoubleQuotedString(const char* string) {
148 Append('"');
149 for (const char* p = string; *p != '\0'; p++) {
150 if (*p == '"') {
151 Append('\\');
152 }
153 Append(*p);
154 }
155 Append('"');
156}
157
158
159void Log::MessageBuilder::Append(String* str) {
160 DisallowHeapAllocation no_gc; // Ensure string stay valid.
Steve Blocka7e24c12009-10-30 11:49:00 +0000161 int length = str->length();
162 for (int i = 0; i < length; i++) {
163 Append(static_cast<char>(str->Get(i)));
164 }
165}
166
Ben Murdoch61f157c2016-09-16 13:49:30 +0100167void Log::MessageBuilder::AppendAddress(Address addr) {
168 Append("%p", static_cast<void*>(addr));
169}
Steve Blocka7e24c12009-10-30 11:49:00 +0000170
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171void Log::MessageBuilder::AppendSymbolName(Symbol* symbol) {
172 DCHECK(symbol);
173 Append("symbol(");
Ben Murdoch61f157c2016-09-16 13:49:30 +0100174 if (!symbol->name()->IsUndefined(symbol->GetIsolate())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 Append("\"");
176 AppendDetailed(String::cast(symbol->name()), false);
177 Append("\" ");
178 }
179 Append("hash %x)", symbol->Hash());
180}
181
182
183void Log::MessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000184 if (str == NULL) return;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185 DisallowHeapAllocation no_gc; // Ensure string stay valid.
Steve Blocka7e24c12009-10-30 11:49:00 +0000186 int len = str->length();
187 if (len > 0x1000)
188 len = 0x1000;
189 if (show_impl_info) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 Append(str->IsOneByteRepresentation() ? 'a' : '2');
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 if (StringShape(str).IsExternal())
192 Append('e');
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000193 if (StringShape(str).IsInternalized())
Steve Blocka7e24c12009-10-30 11:49:00 +0000194 Append('#');
195 Append(":%i:", str->length());
196 }
197 for (int i = 0; i < len; i++) {
198 uc32 c = str->Get(i);
199 if (c > 0xff) {
200 Append("\\u%04x", c);
201 } else if (c < 32 || c > 126) {
202 Append("\\x%02x", c);
203 } else if (c == ',') {
204 Append("\\,");
205 } else if (c == '\\') {
206 Append("\\\\");
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100207 } else if (c == '\"') {
208 Append("\"\"");
Steve Blocka7e24c12009-10-30 11:49:00 +0000209 } else {
210 Append("%lc", c);
211 }
212 }
213}
214
215
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216void Log::MessageBuilder::AppendStringPart(const char* str, int len) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000217 if (pos_ + len > Log::kMessageBufferSize) {
218 len = Log::kMessageBufferSize - pos_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000219 DCHECK(len >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000220 if (len == 0) return;
221 }
Steve Block44f0eee2011-05-26 01:26:41 +0100222 Vector<char> buf(log_->message_buffer_ + pos_,
Steve Blocka7e24c12009-10-30 11:49:00 +0000223 Log::kMessageBufferSize - pos_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000224 StrNCpy(buf, str, len);
Steve Blocka7e24c12009-10-30 11:49:00 +0000225 pos_ += len;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226 DCHECK(pos_ <= Log::kMessageBufferSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000227}
228
229
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230void Log::MessageBuilder::WriteToLogFile() {
231 DCHECK(pos_ <= Log::kMessageBufferSize);
232 // Assert that we do not already have a new line at the end.
233 DCHECK(pos_ == 0 || log_->message_buffer_[pos_ - 1] != '\n');
234 if (pos_ == Log::kMessageBufferSize) pos_--;
235 log_->message_buffer_[pos_++] = '\n';
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000236 const int written = log_->WriteToFile(log_->message_buffer_, pos_);
Steve Block44f0eee2011-05-26 01:26:41 +0100237 if (written != pos_) {
238 log_->stop();
239 log_->logger_->LogFailure();
Steve Blocka7e24c12009-10-30 11:49:00 +0000240 }
241}
242
Steve Block44f0eee2011-05-26 01:26:41 +0100243
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000244} // namespace internal
245} // namespace v8