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

Side by Side Diff: samples/gdb-integration.cc

Issue 6995161: Extend gdb-jit support (OSX/locals+parameters/prettyprint) (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 9 years, 6 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
(Empty)
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <v8.h>
29
30 #include <fcntl.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 /**
36 * This sample program should demonstrate certain aspects of debugging
37 * applications embedding V8 using gdb-jit integration. V8 must be
38 * compiled with this integration enabled; furthermore, V8's
39 * --gdbjit flag must be enabled. Take a look at
40 * samples/gdb-integration-build-run-*.sh and
41 * samples/gdb-integration-run.sh for examples.
42 *
43 * The program reads input stream, processes it line by line and print
44 * the result to output. The actual processing is done by custom JavaScript
45 * script. The script is specified with command line parameters.
46 *
47 * The main cycle of the program will sequentially read lines from standard
48 * input, process them and print to standard output until input closes.
49 * There are 2 possible configuration in regard to main cycle.
50 *
51 * 1. The main cycle is on C++ side. Program should be run with
52 * --main-cycle-in-cpp option. Script must declare a function named
53 * "ProcessLine". The main cycle in C++ reads lines and calls this function
54 * for processing every time. This is a sample script:
55
56 function ProcessLine(input_line) {
57 return ">>>" + input_line + "<<<";
58 }
59
60 *
61 * 2. The main cycle is in JavaScript. Program should be run with
62 * --main-cycle-in-js option. Script gets run one time at all and gets
63 * API of 2 global functions: "read_line" and "print". It should read input
64 * and print converted lines to output itself. This a sample script:
65
66 while (true) {
67 var line = read_line();
68 if (!line) {
69 break;
70 }
71 var res = line + " | " + line;
72 print(res);
73 }
74 * Another global call, "debug_break", is provided; this should break
75 * immediately into the (native) debugger.
76 */
77
78 enum MainCycleType {
79 CycleInCpp,
80 CycleInJs
81 };
82
83 const char* ToCString(const v8::String::Utf8Value& value);
84 void ReportException(v8::TryCatch* handler);
85 v8::Handle<v8::String> ReadFile(const char* name);
86 v8::Handle<v8::String> ReadLine();
87
88 v8::Handle<v8::Value> Print(const v8::Arguments& args);
89 v8::Handle<v8::Value> ReadLine(const v8::Arguments& args);
90 v8::Handle<v8::Value> DebugBreak(const v8::Arguments& args);
91 bool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context,
92 bool report_exceptions);
93
94
95 int RunMain(int argc, char* argv[]) {
96 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
97 v8::HandleScope handle_scope;
98
99 v8::Handle<v8::String> script_source(NULL);
100 v8::Handle<v8::Value> script_name(NULL);
101 int script_param_counter = 0;
102
103 MainCycleType cycle_type = CycleInCpp;
104
105 for (int i = 1; i < argc; i++) {
106 const char* str = argv[i];
107 if (strcmp(str, "-f") == 0) {
108 // Ignore any -f flags for compatibility with the other stand-
109 // alone JavaScript engines.
110 continue;
111 } else if (strcmp(str, "--main-cycle-in-cpp") == 0) {
112 cycle_type = CycleInCpp;
113 } else if (strcmp(str, "--main-cycle-in-js") == 0) {
114 cycle_type = CycleInJs;
115 } else if (strncmp(str, "--", 2) == 0) {
116 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
117 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
118 script_source = v8::String::New(argv[i + 1]);
119 script_name = v8::String::New("unnamed");
120 i++;
121 script_param_counter++;
122 } else {
123 // Use argument as a name of file to load.
124 script_source = ReadFile(str);
125 script_name = v8::String::New(str);
126 if (script_source.IsEmpty()) {
127 printf("Error reading '%s'\n", str);
128 return 1;
129 }
130 script_param_counter++;
131 }
132 }
133
134 if (script_param_counter == 0) {
135 printf("Script is not specified\n");
136 return 1;
137 }
138 if (script_param_counter != 1) {
139 printf("Only one script may be specified\n");
140 return 1;
141 }
142
143 // Create a template for the global object.
144 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
145
146 // Bind the global 'print' function to the C++ Print callback.
147 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
148
149 // Bind the 'debug_break' function to the C++ DebugBreak callback.
150 global->Set(v8::String::New("debug_break"),
151 v8::FunctionTemplate::New(DebugBreak));
152
153 if (cycle_type == CycleInJs) {
154 // Bind the global 'read_line' function to the C++ Print callback.
155 global->Set(v8::String::New("read_line"),
156 v8::FunctionTemplate::New(ReadLine));
157 }
158
159 // Create a new execution environment containing the built-in
160 // functions
161 v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
162 // Enter the newly created execution environment.
163 v8::Context::Scope context_scope(context);
164
165 bool report_exceptions = true;
166
167 v8::Handle<v8::Script> script;
168 {
169 // Compile script in try/catch context.
170 v8::TryCatch try_catch;
171 script = v8::Script::Compile(script_source, script_name);
172 if (script.IsEmpty()) {
173 // Print errors that happened during compilation.
174 if (report_exceptions)
175 ReportException(&try_catch);
176 return 1;
177 }
178 }
179
180 {
181 v8::TryCatch try_catch;
182
183 script->Run();
184 if (try_catch.HasCaught()) {
185 if (report_exceptions)
186 ReportException(&try_catch);
187 return 1;
188 }
189 }
190
191 if (cycle_type == CycleInCpp) {
192 bool res = RunCppCycle(script, v8::Context::GetCurrent(),
193 report_exceptions);
194 return !res;
195 } else {
196 // All is already done.
197 }
198 return 0;
199 }
200
201
202 bool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context,
203 bool report_exceptions) {
204 v8::Handle<v8::String> fun_name = v8::String::New("ProcessLine");
205 v8::Handle<v8::Value> process_val =
206 v8::Context::GetCurrent()->Global()->Get(fun_name);
207
208 // If there is no Process function, or if it is not a function,
209 // bail out
210 if (!process_val->IsFunction()) {
211 printf("Error: Script does not declare 'ProcessLine' global function.\n");
212 return 1;
213 }
214
215 // It is a function; cast it to a Function
216 v8::Handle<v8::Function> process_fun =
217 v8::Handle<v8::Function>::Cast(process_val);
218
219
220 while (!feof(stdin)) {
221 v8::HandleScope handle_scope;
222
223 v8::Handle<v8::String> input_line = ReadLine();
224 if (input_line == v8::Undefined()) {
225 continue;
226 }
227
228 const int argc = 1;
229 v8::Handle<v8::Value> argv[argc] = { input_line };
230
231 v8::Handle<v8::Value> result;
232 {
233 v8::TryCatch try_catch;
234 result = process_fun->Call(v8::Context::GetCurrent()->Global(),
235 argc, argv);
236 if (try_catch.HasCaught()) {
237 if (report_exceptions)
238 ReportException(&try_catch);
239 return false;
240 }
241 }
242 v8::String::Utf8Value str(result);
243 const char* cstr = ToCString(str);
244 printf("%s\n", cstr);
245 }
246
247 return true;
248 }
249
250 int main(int argc, char* argv[]) {
251 int result = RunMain(argc, argv);
252 v8::V8::Dispose();
253 return result;
254 }
255
256
257 // Extracts a C string from a V8 Utf8Value.
258 const char* ToCString(const v8::String::Utf8Value& value) {
259 return *value ? *value : "<string conversion failed>";
260 }
261
262
263 // Reads a file into a v8 string.
264 v8::Handle<v8::String> ReadFile(const char* name) {
265 FILE* file = fopen(name, "rb");
266 if (file == NULL) return v8::Handle<v8::String>();
267
268 fseek(file, 0, SEEK_END);
269 int size = ftell(file);
270 rewind(file);
271
272 char* chars = new char[size + 1];
273 chars[size] = '\0';
274 for (int i = 0; i < size;) {
275 int read = fread(&chars[i], 1, size - i, file);
276 i += read;
277 }
278 fclose(file);
279 v8::Handle<v8::String> result = v8::String::New(chars, size);
280 delete[] chars;
281 return result;
282 }
283
284
285 void ReportException(v8::TryCatch* try_catch) {
286 v8::HandleScope handle_scope;
287 v8::String::Utf8Value exception(try_catch->Exception());
288 const char* exception_string = ToCString(exception);
289 v8::Handle<v8::Message> message = try_catch->Message();
290 if (message.IsEmpty()) {
291 // V8 didn't provide any extra information about this error; just
292 // print the exception.
293 printf("%s\n", exception_string);
294 } else {
295 // Print (filename):(line number): (message).
296 v8::String::Utf8Value filename(message->GetScriptResourceName());
297 const char* filename_string = ToCString(filename);
298 int linenum = message->GetLineNumber();
299 printf("%s:%i: %s\n", filename_string, linenum, exception_string);
300 // Print line of source code.
301 v8::String::Utf8Value sourceline(message->GetSourceLine());
302 const char* sourceline_string = ToCString(sourceline);
303 printf("%s\n", sourceline_string);
304 // Print wavy underline (GetUnderline is deprecated).
305 int start = message->GetStartColumn();
306 for (int i = 0; i < start; i++) {
307 printf(" ");
308 }
309 int end = message->GetEndColumn();
310 for (int i = start; i < end; i++) {
311 printf("^");
312 }
313 printf("\n");
314 }
315 }
316
317
318 // The callback that is invoked by v8 whenever the JavaScript 'print'
319 // function is called. Prints its arguments on stdout separated by
320 // spaces and ending with a newline.
321 v8::Handle<v8::Value> Print(const v8::Arguments& args) {
322 bool first = true;
323 for (int i = 0; i < args.Length(); i++) {
324 v8::HandleScope handle_scope;
325 if (first) {
326 first = false;
327 } else {
328 printf(" ");
329 }
330 v8::String::Utf8Value str(args[i]);
331 const char* cstr = ToCString(str);
332 printf("%s", cstr);
333 }
334 printf("\n");
335 fflush(stdout);
336 return v8::Undefined();
337 }
338
339
340 // The callback invoked by v8 for the 'debug_break' function.
341 v8::Handle<v8::Value> DebugBreak(const v8::Arguments& args) {
342 asm("int $3");
343 return v8::Undefined();
344 }
345
346
347 // The callback that is invoked by v8 whenever the JavaScript 'read_line'
348 // function is called. Reads a string from standard input and returns.
349 v8::Handle<v8::Value> ReadLine(const v8::Arguments& args) {
350 if (args.Length() > 0) {
351 return v8::ThrowException(v8::String::New("Unexpected arguments"));
352 }
353 return ReadLine();
354 }
355
356 v8::Handle<v8::String> ReadLine() {
357 const int kBufferSize = 1024 + 1;
358 char buffer[kBufferSize];
359
360 char* res;
361 {
362 res = fgets(buffer, kBufferSize, stdin);
363 }
364 if (res == NULL) {
365 v8::Handle<v8::Primitive> t = v8::Undefined();
366 return reinterpret_cast<v8::Handle<v8::String>&>(t);
367 }
368 // remove newline char
369 for (char* pos = buffer; *pos != '\0'; pos++) {
370 if (*pos == '\n') {
371 *pos = '\0';
372 break;
373 }
374 }
375 return v8::String::New(buffer);
376 }
OLDNEW
« no previous file with comments | « SConstruct ('k') | samples/gdb-integration.gdb » ('j') | src/gdb-jit.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698