Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: runtime/bin/vmstats_impl.cc

Issue 13603002: Added ctrl-\ command that dumps isolate stacks to dart binary. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/vmstats_impl.h" 5 #include "bin/vmstats_impl.h"
6 6
7 #include "bin/file.h" 7 #include "bin/file.h"
8 #include "bin/log.h" 8 #include "bin/log.h"
9 #include "bin/platform.h" 9 #include "bin/platform.h"
10 #include "bin/resources.h" 10 #include "bin/resources.h"
(...skipping 15 matching lines...) Expand all
26 dart::Monitor* VmStats::instance_monitor_; 26 dart::Monitor* VmStats::instance_monitor_;
27 dart::Mutex* VmStatusService::mutex_; 27 dart::Mutex* VmStatusService::mutex_;
28 28
29 29
30 void VmStats::Start(int port, const char* root_dir) { 30 void VmStats::Start(int port, const char* root_dir) {
31 if (instance_ != NULL) { 31 if (instance_ != NULL) {
32 FATAL("VmStats already started."); 32 FATAL("VmStats already started.");
33 } 33 }
34 instance_ = new VmStats(); 34 instance_ = new VmStats();
35 instance_monitor_ = new dart::Monitor(); 35 instance_monitor_ = new dart::Monitor();
36 Initialize();
37
38 if (port != 0) {
39 StartServer(port, root_dir);
40 }
41 }
42
43
44 void VmStats::StartServer(int port, const char* root_dir) {
36 VmStatusService::InitOnce(); 45 VmStatusService::InitOnce();
37 Socket::Initialize(); 46 Socket::Initialize();
38 47
39 if (root_dir != NULL) { 48 if (root_dir != NULL) {
40 instance_->root_directory_ = root_dir; 49 instance_->root_directory_ = root_dir;
41 } 50 }
42 51
43 // TODO(tball): allow host to be specified. 52 // TODO(tball): allow host to be specified.
44 char* host = const_cast<char*>(DEFAULT_HOST); 53 char* host = const_cast<char*>(DEFAULT_HOST);
45 OSError* os_error; 54 OSError* os_error;
(...skipping 15 matching lines...) Expand all
61 70
62 MonitorLocker ml(instance_monitor_); 71 MonitorLocker ml(instance_monitor_);
63 instance_->running_ = true; 72 instance_->running_ = true;
64 int err = dart::Thread::Start(WebServer, address); 73 int err = dart::Thread::Start(WebServer, address);
65 if (err != 0) { 74 if (err != 0) {
66 Log::PrintErr("Failed starting VmStats thread: %d\n", err); 75 Log::PrintErr("Failed starting VmStats thread: %d\n", err);
67 Shutdown(); 76 Shutdown();
68 } 77 }
69 } 78 }
70 79
71
72 void VmStats::Stop() { 80 void VmStats::Stop() {
73 ASSERT(instance_ != NULL); 81 ASSERT(instance_ != NULL);
74 MonitorLocker ml(instance_monitor_); 82 MonitorLocker ml(instance_monitor_);
75 instance_->running_ = false; 83 instance_->running_ = false;
76 } 84 }
77 85
78 86
79 void VmStats::Shutdown() { 87 void VmStats::Shutdown() {
80 ASSERT(instance_ != NULL); 88 ASSERT(instance_ != NULL);
81 MonitorLocker ml(instance_monitor_); 89 MonitorLocker ml(instance_monitor_);
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 328 }
321 first = false; 329 first = false;
322 free(status); 330 free(status);
323 } 331 }
324 } 332 }
325 text.AddString("\n]\n}\n"); 333 text.AddString("\n]\n}\n");
326 return strdup(text.buf()); 334 return strdup(text.buf());
327 } 335 }
328 336
329 337
338 // Platform-independent version of strndup(), which Windows doesn't have.
339 static char* Strndup(const char* s, intptr_t len) {
340 char* dup = reinterpret_cast<char*>(malloc(len + 1));
341 strncpy(dup, s, len);
342 dup[len] = '\0';
343 return dup;
siva 2013/04/04 00:47:15 Please see comment in other CL about moving this a
Tom Ball 2013/04/04 20:05:53 Done.
344 }
345
346
347 // Advance the scanner to the value token of a specified name-value pair.
348 void SeekNamedValue(const char* name, dart::JSONScanner* scanner) {
349 while (!scanner->EOM()) {
350 scanner->Scan();
351 if (scanner->IsStringLiteral(name)) {
352 scanner->Scan();
353 ASSERT(scanner->CurrentToken() == dart::JSONScanner::TokenColon);
354 scanner->Scan();
355 return;
356 }
357 }
358 }
359
360 void VmStats::DumpStack() {
361 Log::Print("Isolate dump:\n");
362 IsolateTable::iterator itr;
363 for (itr = instance_->isolate_table_.begin();
364 itr != instance_->isolate_table_.end(); ++itr) {
siva 2013/04/04 00:47:15 This map could potentially be changing while this
Tom Ball 2013/04/04 20:05:53 Right -- I added a MutexLocker.
365 Dart_Isolate isolate = itr->second;
366
367 // Print isolate name and details.
368 static char buffer[512];
369 snprintf(buffer, sizeof(buffer),
370 "/isolate/0x%"Px, reinterpret_cast<intptr_t>(isolate));
371 char* isolate_details = VmStatusService::GetVmStatus(buffer);
372 if (isolate_details != NULL) {
373 dart::JSONScanner scanner(isolate_details);
374 SeekNamedValue("name", &scanner);
siva 2013/04/04 00:47:15 How come you are not using the JSONReader class wh
Tom Ball 2013/04/04 20:05:53 Its Seek is limited to top-level name-value pairs,
375 char* name = Strndup(scanner.TokenChars(), scanner.TokenLen());
376 SeekNamedValue("port", &scanner);
377 char* port = Strndup(scanner.TokenChars(), scanner.TokenLen());
378 Log::Print("\"%s\" port=%s\n", name, port);
379 free(isolate_details);
380 free(port);
381 free(name);
382 }
383
384 // Print stack trace.
385 snprintf(buffer, sizeof(buffer),
386 "/isolate/0x%"Px"/stacktrace",
387 reinterpret_cast<intptr_t>(isolate));
388 char* trace = VmStatusService::GetVmStatus(buffer);
389 if (trace != NULL) {
390 dart::JSONScanner scanner(trace);
391 SeekNamedValue("url", &scanner);
392 char* url = Strndup(scanner.TokenChars(), scanner.TokenLen());
393 SeekNamedValue("line", &scanner);
394 char* line = Strndup(scanner.TokenChars(), scanner.TokenLen());
395 SeekNamedValue("function", &scanner);
396 char* function = Strndup(scanner.TokenChars(), scanner.TokenLen());
397 Log::Print(" at %s(%s:%s)\n", function, url, line);
398 free(trace);
399 free(url);
400 free(line);
401 free(function);
402 }
403 }
404 }
405
406
330 // Global static pointer used to ensure a single instance of the class. 407 // Global static pointer used to ensure a single instance of the class.
331 VmStatusService* VmStatusService::instance_ = NULL; 408 VmStatusService* VmStatusService::instance_ = NULL;
332 409
333 410
334 void VmStatusService::InitOnce() { 411 void VmStatusService::InitOnce() {
335 ASSERT(VmStatusService::instance_ == NULL); 412 ASSERT(VmStatusService::instance_ == NULL);
336 VmStatusService::instance_ = new VmStatusService(); 413 VmStatusService::instance_ = new VmStatusService();
337 VmStatusService::mutex_ = new dart::Mutex(); 414 VmStatusService::mutex_ = new dart::Mutex();
338 415
339 // Register built-in status plug-ins. RegisterPlugin is not used because 416 // Register built-in status plug-ins. RegisterPlugin is not used because
(...skipping 25 matching lines...) Expand all
365 VmStatusPlugin* plugin = instance_->registered_plugin_list_; 442 VmStatusPlugin* plugin = instance_->registered_plugin_list_;
366 while (plugin != NULL) { 443 while (plugin != NULL) {
367 char* result = (plugin->callback())(request); 444 char* result = (plugin->callback())(request);
368 if (result != NULL) { 445 if (result != NULL) {
369 return result; 446 return result;
370 } 447 }
371 plugin = plugin->next(); 448 plugin = plugin->next();
372 } 449 }
373 return NULL; 450 return NULL;
374 } 451 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698