📄 test-debug.cc.svn-base
字号:
// Copyright 2007-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include <stdlib.h>#include "v8.h"#include "api.h"#include "debug.h"#include "platform.h"#include "stub-cache.h"#include "cctest.h"using ::v8::internal::EmbeddedVector;using ::v8::internal::Object;using ::v8::internal::OS;using ::v8::internal::Handle;using ::v8::internal::Heap;using ::v8::internal::JSGlobalObject;using ::v8::internal::Code;using ::v8::internal::Debug;using ::v8::internal::Debugger;using ::v8::internal::StepAction;using ::v8::internal::StepIn; // From StepAction enumusing ::v8::internal::StepNext; // From StepAction enumusing ::v8::internal::StepOut; // From StepAction enum// Size of temp buffer for formatting small strings.#define SMALL_STRING_BUFFER_SIZE 80// --- A d d i t i o n a l C h e c k H e l p e r s// Helper function used by the CHECK_EQ function when given Address// arguments. Should not be called directly.static inline void CheckEqualsHelper(const char* file, int line, const char* expected_source, ::v8::internal::Address expected, const char* value_source, ::v8::internal::Address value) { if (expected != value) { V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n# " "Expected: %i\n# Found: %i", expected_source, value_source, expected, value); }}// Helper function used by the CHECK_NE function when given Address// arguments. Should not be called directly.static inline void CheckNonEqualsHelper(const char* file, int line, const char* unexpected_source, ::v8::internal::Address unexpected, const char* value_source, ::v8::internal::Address value) { if (unexpected == value) { V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %i", unexpected_source, value_source, value); }}// Helper function used by the CHECK function when given code// arguments. Should not be called directly.static inline void CheckEqualsHelper(const char* file, int line, const char* expected_source, const Code* expected, const char* value_source, const Code* value) { if (expected != value) { V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n# " "Expected: %p\n# Found: %p", expected_source, value_source, expected, value); }}static inline void CheckNonEqualsHelper(const char* file, int line, const char* expected_source, const Code* expected, const char* value_source, const Code* value) { if (expected == value) { V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %p", expected_source, value_source, value); }}// --- H e l p e r C l a s s e s// Helper class for creating a V8 enviromnent for running testsclass DebugLocalContext { public: inline DebugLocalContext( v8::ExtensionConfiguration* extensions = 0, v8::Handle<v8::ObjectTemplate> global_template = v8::Handle<v8::ObjectTemplate>(), v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) : context_(v8::Context::New(extensions, global_template, global_object)) { context_->Enter(); } inline ~DebugLocalContext() { context_->Exit(); context_.Dispose(); } inline v8::Context* operator->() { return *context_; } inline v8::Context* operator*() { return *context_; } inline bool IsReady() { return !context_.IsEmpty(); } void ExposeDebug() { // Expose the debug context global object in the global object for testing. Debug::Load(); Handle<JSGlobalObject> global(Handle<JSGlobalObject>::cast( v8::Utils::OpenHandle(*context_->Global()))); Handle<JSGlobalObject> debug_global(JSGlobalObject::cast( Debug::debug_context()->global())); debug_global->set_security_token(global->security_token()); Handle<v8::internal::String> debug_string = v8::internal::Factory::LookupAsciiSymbol("debug"); SetProperty(global, debug_string, debug_global, DONT_ENUM); } private: v8::Persistent<v8::Context> context_;};// --- H e l p e r F u n c t i o n s// Compile and run the supplied source and return the fequested function.static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, const char* source, const char* function_name) { v8::Script::Compile(v8::String::New(source))->Run(); return v8::Local<v8::Function>::Cast( (*env)->Global()->Get(v8::String::New(function_name)));}// Helper function that compiles and runs the source.static v8::Local<v8::Value> CompileRun(const char* source) { return v8::Script::Compile(v8::String::New(source))->Run();}// Is there any debug info for the function?static bool HasDebugInfo(v8::Handle<v8::Function> fun) { Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); return Debug::HasDebugInfo(shared);}// Set a break point in a function and return the associated break point// number.static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { static int break_point = 0; Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); Debug::SetBreakPoint( shared, position, Handle<Object>(v8::internal::Smi::FromInt(++break_point))); return break_point;}// Set a break point in a function and return the associated break point// number.static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { return SetBreakPoint(v8::Utils::OpenHandle(*fun), position);}// Set a break point in a function using the Debug object and return the// associated break point number.static int SetBreakPointFromJS(const char* function_name, int line, int position) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.setBreakPoint(%s,%d,%d)", function_name, line, position); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; v8::Handle<v8::String> str = v8::String::New(buffer.start()); return v8::Script::Compile(str)->Run()->Int32Value();}// Set a break point in a script using the global Debug object.static int SetScriptBreakPointFromJS(const char* script_data, int line, int column) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; if (column >= 0) { // Column specified set script break point on precise location. OS::SNPrintF(buffer, "debug.Debug.setScriptBreakPoint(\"%s\",%d,%d)", script_data, line, column); } else { // Column not specified set script break point on line. OS::SNPrintF(buffer, "debug.Debug.setScriptBreakPoint(\"%s\",%d)", script_data, line); } buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; v8::Handle<v8::String> str = v8::String::New(buffer.start()); return v8::Script::Compile(str)->Run()->Int32Value();}// Clear a break point.static void ClearBreakPoint(int break_point) { Debug::ClearBreakPoint( Handle<Object>(v8::internal::Smi::FromInt(break_point)));}// Clear a break point using the global Debug object.static void ClearBreakPointFromJS(int break_point_number) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.clearBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; v8::Script::Compile(v8::String::New(buffer.start()))->Run();}static void EnableScriptBreakPointFromJS(int break_point_number) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.enableScriptBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; v8::Script::Compile(v8::String::New(buffer.start()))->Run();}static void DisableScriptBreakPointFromJS(int break_point_number) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.disableScriptBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; v8::Script::Compile(v8::String::New(buffer.start()))->Run();}static void ChangeScriptBreakPointConditionFromJS(int break_point_number, const char* condition) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")", break_point_number, condition); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; v8::Script::Compile(v8::String::New(buffer.start()))->Run();}static void ChangeScriptBreakPointIgnoreCountFromJS(int break_point_number, int ignoreCount) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; OS::SNPrintF(buffer, "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", break_point_number, ignoreCount); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; v8::Script::Compile(v8::String::New(buffer.start()))->Run();}// Change break on exception.static void ChangeBreakOnException(bool caught, bool uncaught) { Debug::ChangeBreakOnException(v8::internal::BreakException, caught); Debug::ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught);}// Change break on exception using the global Debug object.static void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) { if (caught) { v8::Script::Compile( v8::String::New("debug.Debug.setBreakOnException()"))->Run(); } else { v8::Script::Compile( v8::String::New("debug.Debug.clearBreakOnException()"))->Run(); } if (uncaught) { v8::Script::Compile( v8::String::New("debug.Debug.setBreakOnUncaughtException()"))->Run(); } else { v8::Script::Compile( v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run(); }}// Prepare to step to next break location.static void PrepareStep(StepAction step_action) { Debug::PrepareStep(step_action, 1);}// This function is in namespace v8::internal to be friend with class// v8::internal::Debug.namespace v8 { namespace internal { // NOLINT// Collect the currently debugged functions.Handle<FixedArray> GetDebuggedFunctions() { v8::internal::DebugInfoListNode* node = Debug::debug_info_list_; // Find the number of debugged functions. int count = 0; while (node) { count++; node = node->next(); } // Allocate array for the debugged functions Handle<FixedArray> debugged_functions = v8::internal::Factory::NewFixedArray(count); // Run through the debug info objects and collect all functions. count = 0; while (node) { debugged_functions->set(count++, *node->debug_info()); node = node->next(); } return debugged_functions;}static Handle<Code> ComputeCallDebugBreak(int argc) { CALL_HEAP_FUNCTION(v8::internal::StubCache::ComputeCallDebugBreak(argc), Code);}} } // namespace v8::internal// Inherit from BreakLocationIterator to get access to protected parts for// testing.class TestBreakLocationIterator: public v8::internal::BreakLocationIterator { public: explicit TestBreakLocationIterator(Handle<v8::internal::DebugInfo> debug_info) : BreakLocationIterator(debug_info, v8::internal::SOURCE_BREAK_LOCATIONS) {} v8::internal::RelocIterator* it() { return reloc_iterator_; } v8::internal::RelocIterator* it_original() { return reloc_iterator_original_; }};// Compile a function, set a break point and check that the call at the break// location in the code is the expected debug_break function.void CheckDebugBreakFunction(DebugLocalContext* env, const char* source, const char* name, int position, v8::internal::RelocInfo::Mode mode, Code* debug_break) { // Create function and set the break point.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -