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

Side by Side Diff: shell/tracer.cc

Issue 1105773002: Teach the mojo_shell --trace-startup flag to gather data from services (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 7 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "shell/tracer.h" 5 #include "shell/tracer.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 11 matching lines...) Expand all
22 } 22 }
23 23
24 void Tracer::Start(const std::string& categories) { 24 void Tracer::Start(const std::string& categories) {
25 tracing_ = true; 25 tracing_ = true;
26 base::trace_event::CategoryFilter category_filter(categories); 26 base::trace_event::CategoryFilter category_filter(categories);
27 base::trace_event::TraceLog::GetInstance()->SetEnabled( 27 base::trace_event::TraceLog::GetInstance()->SetEnabled(
28 category_filter, base::trace_event::TraceLog::RECORDING_MODE, 28 category_filter, base::trace_event::TraceLog::RECORDING_MODE,
29 base::trace_event::TraceOptions(base::trace_event::RECORD_UNTIL_FULL)); 29 base::trace_event::TraceOptions(base::trace_event::RECORD_UNTIL_FULL));
30 } 30 }
31 31
32 void Tracer::StartCollectingFromTracingService(
33 tracing::TraceCoordinatorPtr coordinator) {
34 coordinator_ = coordinator.Pass();
35 mojo::DataPipe data_pipe;
36 coordinator_->Start(data_pipe.producer_handle.Pass(), "*");
37 drainer_.reset(new mojo::common::DataPipeDrainer(
38 this, data_pipe.consumer_handle.Pass()));
39 }
40
32 void Tracer::StopAndFlushToFile(const std::string& filename) { 41 void Tracer::StopAndFlushToFile(const std::string& filename) {
33 if (tracing_) 42 if (tracing_)
34 StopTracingAndFlushToDisk(filename); 43 StopTracingAndFlushToDisk(filename);
35 } 44 }
36 45
46 void Tracer::ConnectToController(
47 mojo::InterfaceRequest<tracing::TraceController> request) {
48 auto impl = new mojo::TraceControllerImpl(request.Pass());
49 impl->set_tracing_already_started(tracing_);
50 }
51
52 void Tracer::StopTracingAndFlushToDisk(const std::string& filename) {
53 tracing_ = false;
54 trace_file_ = fopen(filename.c_str(), "w+");
55 trace_filename_ = filename;
56 PCHECK(trace_file_);
viettrungluu 2015/04/28 00:42:17 nit: move this to be immediately after the fopen()
57 static const char kStart[] = "{\"traceEvents\":[";
58 PCHECK(fwrite(kStart, 1, strlen(kStart), trace_file_) == strlen(kStart));
59
60 // At this point we might be connected to the tracing service, in which case
61 // we want to tell it to stop tracing and we will send the data we've
62 // collected in process to it.
63 if (coordinator_) {
64 coordinator_->StopAndFlush();
65 } else {
66 // Or we might not be connected. If we aren't connected to the tracing
67 // service we want to collect the tracing data gathered ourselves and flush
68 // it to disk. We do this in a blocking fashion (for this thread) so we can
69 // gather as much data as possible on shutdown.
70 base::trace_event::TraceLog::GetInstance()->SetDisabled();
71 {
72 base::WaitableEvent flush_complete_event(false, false);
73 // TraceLog::Flush requires a message loop but we've already shut ours
74 // down.
75 // Spin up a new thread to flush things out.
76 base::Thread flush_thread("mojo_shell_trace_event_flush");
77 flush_thread.Start();
78 flush_thread.message_loop()->PostTask(
79 FROM_HERE,
80 base::Bind(&Tracer::EndTraceAndFlush, base::Unretained(this),
81 filename,
82 base::Bind(&base::WaitableEvent::Signal,
83 base::Unretained(&flush_complete_event))));
84 base::trace_event::TraceLog::GetInstance()
85 ->SetCurrentThreadBlocksMessageLoop();
86 flush_complete_event.Wait();
87 }
88 }
89 }
90
91 void Tracer::WriteFooterAndClose() {
92 static const char kEnd[] = "]}";
93 PCHECK(fwrite(kEnd, 1, strlen(kEnd), trace_file_) == strlen(kEnd));
94 PCHECK(fclose(trace_file_) == 0);
95 trace_file_ = nullptr;
96 LOG(INFO) << "Wrote trace data to " << trace_filename_;
97 }
98
37 void Tracer::EndTraceAndFlush(const std::string& filename, 99 void Tracer::EndTraceAndFlush(const std::string& filename,
38 const base::Closure& done_callback) { 100 const base::Closure& done_callback) {
39 trace_file_ = fopen(filename.c_str(), "w+");
40 PCHECK(trace_file_);
41 static const char kStart[] = "{\"traceEvents\":[";
42 fwrite(kStart, 1, strlen(kStart), trace_file_);
43 base::trace_event::TraceLog::GetInstance()->SetDisabled(); 101 base::trace_event::TraceLog::GetInstance()->SetDisabled();
44 base::trace_event::TraceLog::GetInstance()->Flush(base::Bind( 102 base::trace_event::TraceLog::GetInstance()->Flush(base::Bind(
45 &Tracer::WriteTraceDataCollected, base::Unretained(this), done_callback)); 103 &Tracer::WriteTraceDataCollected, base::Unretained(this), done_callback));
46 } 104 }
47 105
48 void Tracer::WriteTraceDataCollected( 106 void Tracer::WriteTraceDataCollected(
49 const base::Closure& done_callback, 107 const base::Closure& done_callback,
50 const scoped_refptr<base::RefCountedString>& events_str, 108 const scoped_refptr<base::RefCountedString>& events_str,
51 bool has_more_events) { 109 bool has_more_events) {
52 if (events_str->size()) { 110 if (events_str->size()) {
53 if (first_chunk_written_) 111 WriteCommaIfNeeded();
54 fwrite(",", 1, 1, trace_file_);
55 112
56 first_chunk_written_ = true; 113 PCHECK(fwrite(events_str->data().c_str(), 1, events_str->data().length(),
57 fwrite(events_str->data().c_str(), 1, events_str->data().length(), 114 trace_file_) == events_str->data().length());
58 trace_file_);
59 } 115 }
60 116
61 if (!has_more_events) { 117 if (!has_more_events && !done_callback.is_null())
62 static const char kEnd[] = "]}";
63 fwrite(kEnd, 1, strlen(kEnd), trace_file_);
64 PCHECK(fclose(trace_file_) == 0);
65 trace_file_ = nullptr;
66 done_callback.Run(); 118 done_callback.Run();
67 }
68 } 119 }
69 120
70 void Tracer::StopTracingAndFlushToDisk(const std::string& filename) { 121 void Tracer::OnDataAvailable(const void* data, size_t num_bytes) {
viettrungluu 2015/04/28 00:42:17 Hmmm, this seems sketchy to me -- you may not get
71 tracing_ = false; 122 const char* chars = static_cast<const char*>(data);
72 base::trace_event::TraceLog::GetInstance()->SetDisabled(); 123 if (num_bytes == 1u && *chars == ',')
73 base::WaitableEvent flush_complete_event(false, false); 124 return;
74 // TraceLog::Flush requires a message loop but we've already shut ours down. 125 WriteCommaIfNeeded();
75 // Spin up a new thread to flush things out. 126 PCHECK(fwrite(chars, 1, num_bytes, trace_file_) == num_bytes);
76 base::Thread flush_thread("mojo_shell_trace_event_flush"); 127 }
77 flush_thread.Start(); 128
78 flush_thread.message_loop()->PostTask( 129 void Tracer::OnDataComplete() {
79 FROM_HERE, 130 drainer_.reset();
80 base::Bind(&Tracer::EndTraceAndFlush, base::Unretained(this), filename, 131 coordinator_.reset();
81 base::Bind(&base::WaitableEvent::Signal, 132 WriteFooterAndClose();
82 base::Unretained(&flush_complete_event)))); 133 }
83 flush_complete_event.Wait(); 134
84 LOG(INFO) << "Wrote trace data to " << filename; 135 void Tracer::WriteCommaIfNeeded() {
136 if (first_chunk_written_)
137 PCHECK(fwrite(",", 1, 1, trace_file_) == 1);
138 first_chunk_written_ = true;
85 } 139 }
86 140
87 } // namespace shell 141 } // namespace shell
OLDNEW
« no previous file with comments | « shell/tracer.h ('k') | sky/tools/debugger/debugger.cc » ('j') | sky/tools/debugger/debugger.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698