WebKit Bugzilla
Attachment 341210 Details for
Bug 183744
: Add some tests for lldb_webkit.py
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch and unit tests that run fast
bug-183744-20180524110643.patch (text/plain), 37.51 KB, created by
Daniel Bates
on 2018-05-24 11:06:43 PDT
(
hide
)
Description:
Patch and unit tests that run fast
Filename:
MIME Type:
Creator:
Daniel Bates
Created:
2018-05-24 11:06:43 PDT
Size:
37.51 KB
patch
obsolete
>Subversion Revision: 231991 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index f569f3b1a2ad65a61dd5e388e96f09e05b8adb02..624fab29134c5e2d7d76bb9d04446ebbf669e525 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,77 @@ >+2018-05-24 Daniel Bates <dabates@apple.com> >+ >+ Add some tests for lldb_webkit.py >+ https://bugs.webkit.org/show_bug.cgi?id=183744 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Adds some tests to ensure we do not regress LLDB pretty-printing of WTF::StringImpl >+ and WTF::String objects. >+ >+ The tests make use of the LLDB Python API and a simple debug-built test program, >+ lldbWebKitTester, to run. The script test-webkitpy will only run the LLDB unit >+ tests if lldbWebKitTester exists in the debug built products directory and the >+ LLDB Python module can be found. For now, we build lldbWebKitTester and run >+ the LLDB unit tests only on Mac. >+ >+ * Makefile: Build the simple test tool lldbWebKitTester on Mac. Although this makefile >+ supports building the tool for either Release and Debug we only support running the tests >+ with a debug-built version of lldbWebKitTester. We should look to override a specified >+ configuration style and always build lldbWebKitTester for Debug. >+ * Scripts/dump-class-layout: Extract logic to compute the path to the LLDB Python module >+ from here to Scripts/webkitpy/common/system/systemhost.py so that it can used by both >+ this script and lldb/lldb_webkit_unittest.py. Also import the lldb module at the top of >+ the file and take advantage of Python's default error semantics to throw an exception >+ if the import fails instead of handling it ourself. This has the side effect that we >+ now always import the LLDB Python module even if this script is invoked with --help. >+ If this turns out to be a significant annoyance then we can look to dynamically import >+ the module as we did before this change. >+ (webkit_build_dir): >+ (main): >+ (developer_dir): Deleted. >+ (import_lldb): Deleted. >+ * Scripts/webkitpy/common/checkout/scm/scm_unittest.py: Update FIXME comment to reflect >+ that fact that test-webkitpy does not support class and module fixtures. This is because >+ test-webkitpy currently implements parallelism by breaking down existing test classes >+ into individual test methods itself and having each worker run exactly one test method (via >+ unittest.TestLoader.loadTestsFromName()) at a time. As a result of this reorganization, >+ setUpModule()/setUpClass() are called for each test method as opposed to once per test >+ class/test module. >+ (remove_dir): Ditto. >+ * Scripts/webkitpy/common/system/systemhost.py: >+ (SystemHost): >+ (SystemHost.path_to_lldb_python_directory): Added. >+ * Scripts/webkitpy/test/main.py: >+ (maybe_add_lldb_webkit_tests): Added. >+ (main): Call maybe_add_lldb_webkit_tests() to conditionally add the lldb_webkit tests >+ to the test search path. >+ * lldb/lldbWebKitTester/Configurations/Base.xcconfig: Added. >+ * lldb/lldbWebKitTester/Configurations/DebugRelease.xcconfig: Added. >+ * lldb/lldbWebKitTester/Configurations/lldbWebKitTester.xcconfig: Added. >+ * lldb/lldbWebKitTester/Makefile: Added. >+ * lldb/lldbWebKitTester/lldbWebKitTester.xcodeproj/project.pbxproj: Added. >+ * lldb/lldbWebKitTester/main.cpp: Added. >+ (breakForTestingSummaryProviders): >+ (utf16String): >+ (testSummaryProviders): >+ (main): >+ * lldb/lldb_webkit_unittest.py: Added. >+ (destroy_cached_debug_session): >+ (LLDBDebugSession): >+ (LLDBDebugSession.setup): >+ (LLDBDebugSession.tearDown): >+ (TestSummaryProviders): >+ (TestSummaryProviders.setUpClass): >+ (TestSummaryProviders._sbFrame): >+ (TestSummaryProviders.serial_test_WTFStringImpl_SummaryProvider_null_string): >+ (TestSummaryProviders.serial_test_WTFStringImpl_SummaryProvider_empty_string): >+ (TestSummaryProviders.serial_test_WTFStringImpl_SummaryProvider_8bit_string): >+ (TestSummaryProviders.serial_test_WTFStringImpl_SummaryProvider_16bit_string): >+ (TestSummaryProviders.serial_test_WTFString_SummaryProvider_null_string): >+ (TestSummaryProviders.serial_test_WTFString_SummaryProvider_empty_string): >+ (TestSummaryProviders.serial_test_WTFString_SummaryProvider_8bit_string): >+ (TestSummaryProviders.serial_test_WTFString_SummaryProvider_16bit_string): >+ > 2018-05-21 Daniel Bates <dabates@apple.com> > > test-webkitpy messages logged using __main__ logger are not displayed >diff --git a/Tools/Makefile b/Tools/Makefile >index 6a1f77ce63573e5fe891034768253730045b9243..ca07f1881bc91fe8e522d66e3df7b81f7580f44c 100644 >--- a/Tools/Makefile >+++ b/Tools/Makefile >@@ -2,7 +2,7 @@ MODULES = DumpRenderTree WebKitTestRunner MiniBrowser ../Source/ThirdParty/gtest > > ifneq (,$(SDKROOT)) > ifeq (,$(findstring macosx,$(SDKROOT))) >- MODULES = DumpRenderTree WebKitTestRunner ../Source/ThirdParty/gtest/xcode TestWebKitAPI >+ MODULES = DumpRenderTree WebKitTestRunner ../Source/ThirdParty/gtest/xcode TestWebKitAPI lldb/lldbWebKitTester > endif > ifneq (,$(findstring iphone,$(SDKROOT))) > MODULES += MobileMiniBrowser >diff --git a/Tools/Scripts/dump-class-layout b/Tools/Scripts/dump-class-layout >index d41864455836e3b0e2b06546b9bab62668586ec5..6f6eba42de8175362b2c21977916d874b5504cd5 100755 >--- a/Tools/Scripts/dump-class-layout >+++ b/Tools/Scripts/dump-class-layout >@@ -31,6 +31,9 @@ import os > import subprocess > from sets import Set > >+from webkitpy.common.system.systemhost import SystemHost >+sys.path.append(SystemHost().path_to_lldb_python_directory()) >+import lldb > > framework = "WebCore" > build_directory = "" >@@ -41,21 +44,6 @@ def webkit_build_dir(): > scriptpath = os.path.dirname(os.path.realpath(__file__)) > return subprocess.check_output([os.path.join(scriptpath, "webkit-build-directory"), "--top-level"]).strip() > >-def developer_dir(): >- return subprocess.check_output(["xcode-select", "--print-path"]) >- >-def import_lldb(): >- xcode_contents_path = os.path.split(developer_dir())[0] >- lldb_framework_path = os.path.join(xcode_contents_path, "SharedFrameworks", "LLDB.framework", "Resources", "Python") >- sys.path.append(lldb_framework_path) >- >- LLDB_MODULE_NAME = "lldb" >- try: >- globals()[LLDB_MODULE_NAME] = __import__(LLDB_MODULE_NAME) >- except ImportError: >- print "Failed to import {} from {}".format(LLDB_MODULE_NAME, lldb_framework_path) >- sys.exit(1) >- > def verify_type(target, type): > typename = type.GetName() > seenOffset = Set() >@@ -196,7 +184,6 @@ def main(): > build_dir = args.build_directory > > target_path = os.path.join(build_dir, args.config, args.framework + ".framework", args.framework); >- import_lldb() > dump_class(target_path, args.classname, args.arch) > > if __name__ == "__main__": >diff --git a/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py b/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py >index 8921ca982864b741949b2664598810e7eb43300f..22eb7ce4a458cf072be7d301df25472884e83bbc 100644 >--- a/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py >+++ b/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py >@@ -60,7 +60,8 @@ from .svn import SVN > > # We cache the mock SVN repo so that we don't create it again for each call to an SVNTest or GitTest test_ method. > # We store it in a global variable so that we can delete this cached repo on exit(3). >-# FIXME: Remove this once we migrate to Python 2.7. Unittest in Python 2.7 supports module-specific setup and teardown functions. >+# FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule() >+# are called exactly once per class/module). > cached_svn_repo_path = None > > >@@ -70,7 +71,8 @@ def remove_dir(path): > shutil.rmtree(path) > > >-# FIXME: Remove this once we migrate to Python 2.7. Unittest in Python 2.7 supports module-specific setup and teardown functions. >+# FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule() >+# are called exactly once per class/module). > @atexit.register > def delete_cached_mock_repo_at_exit(): > if cached_svn_repo_path: >diff --git a/Tools/Scripts/webkitpy/common/system/systemhost.py b/Tools/Scripts/webkitpy/common/system/systemhost.py >index a15342201d833414731ebd0f76f7179a6f0bd6e3..43d6d79fc472394001fc94f942b199a4a9cdf8b1 100644 >--- a/Tools/Scripts/webkitpy/common/system/systemhost.py >+++ b/Tools/Scripts/webkitpy/common/system/systemhost.py >@@ -47,3 +47,9 @@ class SystemHost(object): > > def symbolicate_crash_log_if_needed(self, path): > return self.filesystem.read_text_file(path) >+ >+ def path_to_lldb_python_directory(self): >+ if not self.platform.is_mac(): >+ return '' >+ xcode_developer_directory = self.executive.run_command(['xcode-select', '--print-path'], return_stderr=False).rstrip() >+ return self.filesystem.abspath(self.filesystem.join(xcode_developer_directory, '..', 'SharedFrameworks', 'LLDB.framework', 'Versions', 'A', 'Resources', 'Python')) >diff --git a/Tools/Scripts/webkitpy/test/main.py b/Tools/Scripts/webkitpy/test/main.py >index 5facaa546dee9658bac9848ea02e1fc482a0f2ef..cb0cd0af20ae1e602412181a4271dc56cca7fd7a 100644 >--- a/Tools/Scripts/webkitpy/test/main.py >+++ b/Tools/Scripts/webkitpy/test/main.py >@@ -1,5 +1,6 @@ > # Copyright (C) 2012 Google, Inc. > # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) >+# Copyright (C) 2018 Apple Inc. All rights reserved. > # > # Redistribution and use in source and binary forms, with or without > # modification, are permitted provided that the following conditions >@@ -38,6 +39,8 @@ import unittest > > from webkitpy.common.system.logutils import configure_logging > from webkitpy.common.system.filesystem import FileSystem >+from webkitpy.common.system.systemhost import SystemHost >+from webkitpy.port.config import Config > from webkitpy.test.finder import Finder > from webkitpy.test.printer import Printer > from webkitpy.test.runner import Runner, unit_test_name >@@ -45,6 +48,21 @@ from webkitpy.test.runner import Runner, unit_test_name > _log = logging.getLogger(__name__) > > >+def maybe_add_lldb_webkit_tests(tester, webkit_root): >+ host = SystemHost() >+ lldb_python_directory = host.path_to_lldb_python_directory() >+ if not os.path.isdir(lldb_python_directory): >+ _log.info("Skipping lldb_webkit tests; could not find LLDB Python module directory '{}'.".format(lldb_python_directory)) >+ return >+ build_directory = Config(host.executive, host.filesystem).build_directory('Debug') >+ lldb_webkit_tester_executable = os.path.join(build_directory, 'lldbWebKitTester') >+ if not os.path.exists(lldb_webkit_tester_executable): >+ _log.info("Skipping lldb_webkit tests; could not find '{}'.".format(lldb_webkit_tester_executable)) >+ return >+ if lldb_python_directory not in sys.path: >+ sys.path.append(lldb_python_directory) >+ tester.add_tree(os.path.join(webkit_root, 'Tools', 'lldb')) >+ > def main(): > configure_logging(logger=_log) > >@@ -58,6 +76,8 @@ def main(): > if not (sys.platform.startswith('win') or sys.platform == 'cygwin'): > tester.add_tree(os.path.join(webkit_root, 'Source', 'WebKit', 'Scripts'), 'webkit') > >+ maybe_add_lldb_webkit_tests(tester, webkit_root) >+ > tester.skip(('webkitpy.common.checkout.scm.scm_unittest',), 'are really, really, slow', 31818) > if sys.platform.startswith('win'): > tester.skip(('webkitpy.common.checkout', 'webkitpy.common.config', 'webkitpy.tool'), 'fail horribly on win32', 54526) >diff --git a/Tools/lldb/lldbWebKitTester/Configurations/Base.xcconfig b/Tools/lldb/lldbWebKitTester/Configurations/Base.xcconfig >new file mode 100644 >index 0000000000000000000000000000000000000000..e20bc5d774ff3104030beb3cdfe20fd19567207b >--- /dev/null >+++ b/Tools/lldb/lldbWebKitTester/Configurations/Base.xcconfig >@@ -0,0 +1,90 @@ >+// Copyright (C) 2015-2018 Apple Inc. All rights reserved. >+// >+// Redistribution and use in source and binary forms, with or without >+// modification, are permitted provided that the following conditions >+// are met: >+// 1. Redistributions of source code must retain the above copyright >+// notice, this list of conditions and the following disclaimer. >+// 2. 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. >+// >+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "../../../../Internal/Configurations/HaveInternalSDK.xcconfig" >+ >+USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION)); >+USE_INTERNAL_SDK_Production = YES; >+USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK); >+USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK); >+ >+CLANG_CXX_LANGUAGE_STANDARD = gnu++14; >+CLANG_CXX_LIBRARY = libc++; >+CLANG_WARN_BOOL_CONVERSION = YES; >+CLANG_WARN_CONSTANT_CONVERSION = YES; >+CLANG_WARN_CXX0X_EXTENSIONS = NO; >+CLANG_WARN_EMPTY_BODY = YES; >+CLANG_WARN_ENUM_CONVERSION = YES; >+CLANG_WARN_INT_CONVERSION = YES; >+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; >+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym; >+GCC_C_LANGUAGE_STANDARD = gnu99; >+GCC_DEBUGGING_SYMBOLS = default; >+GCC_ENABLE_CPP_EXCEPTIONS = NO; >+GCC_ENABLE_CPP_RTTI = YES; >+GCC_ENABLE_OBJC_EXCEPTIONS = YES; >+GCC_ENABLE_SYMBOL_SEPARATION = NO; >+GCC_FAST_OBJC_DISPATCH = YES; >+GCC_GENERATE_DEBUGGING_SYMBOLS = YES; >+GCC_OBJC_CALL_CXX_CDTORS = YES; >+GCC_PRECOMPILE_PREFIX_HEADER = YES; >+GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) $(inherited); >+GCC_STRICT_ALIASING = YES; >+GCC_THREADSAFE_STATICS = NO; >+GCC_TREAT_WARNINGS_AS_ERRORS = YES; >+GCC_WARN_64_TO_32_BIT_CONVERSION_ = YES; >+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; >+GCC_WARN_ABOUT_MISSING_NEWLINE = YES; >+GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; >+GCC_WARN_ABOUT_RETURN_TYPE = YES; >+GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; >+GCC_WARN_SIGN_COMPARE = YES; >+GCC_WARN_UNDECLARED_SELECTOR = YES; >+GCC_WARN_UNINITIALIZED_AUTOS = YES; >+GCC_WARN_UNUSED_FUNCTION = YES; >+GCC_WARN_UNUSED_VARIABLE = NO; >+WARNING_CFLAGS = -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough; >+ >+HEADER_SEARCH_PATHS = ${BUILT_PRODUCTS_DIR}/usr/local/include; >+ >+TARGET_MAC_OS_X_VERSION_MAJOR = $(TARGET_MAC_OS_X_VERSION_MAJOR$(MACOSX_DEPLOYMENT_TARGET:suffix:identifier)); >+TARGET_MAC_OS_X_VERSION_MAJOR_10 = 101000; >+TARGET_MAC_OS_X_VERSION_MAJOR_11 = 101100; >+TARGET_MAC_OS_X_VERSION_MAJOR_12 = 101200; >+TARGET_MAC_OS_X_VERSION_MAJOR_13 = 101300; >+ >+// DEBUG_DEFINES, GCC_OPTIMIZATION_LEVEL, STRIP_INSTALLED_PRODUCT and DEAD_CODE_STRIPPING vary between the debug and normal variants. >+// We set up the values for each variant here, and have the Debug configuration in the Xcode project use the _debug variant. >+DEBUG_DEFINES_debug = ; >+DEBUG_DEFINES_normal = NDEBUG; >+DEBUG_DEFINES = $(DEBUG_DEFINES_$(CURRENT_VARIANT)); >+ >+GCC_OPTIMIZATION_LEVEL = $(GCC_OPTIMIZATION_LEVEL_$(CURRENT_VARIANT)); >+GCC_OPTIMIZATION_LEVEL_normal = 3; >+GCC_OPTIMIZATION_LEVEL_debug = 0; >+ >+SDKROOT = macosx.internal; >+ >+OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS); >+OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS); >+OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS); >diff --git a/Tools/lldb/lldbWebKitTester/Configurations/DebugRelease.xcconfig b/Tools/lldb/lldbWebKitTester/Configurations/DebugRelease.xcconfig >new file mode 100644 >index 0000000000000000000000000000000000000000..9eade9c1cae379a3ee19208b797dfcc112a75745 >--- /dev/null >+++ b/Tools/lldb/lldbWebKitTester/Configurations/DebugRelease.xcconfig >@@ -0,0 +1,41 @@ >+// Copyright (C) 2015-2018 Apple Inc. All rights reserved. >+// >+// Redistribution and use in source and binary forms, with or without >+// modification, are permitted provided that the following conditions >+// are met: >+// 1. Redistributions of source code must retain the above copyright >+// notice, this list of conditions and the following disclaimer. >+// 2. 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. >+// >+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "Base.xcconfig" >+ >+ONLY_ACTIVE_ARCH = YES; >+ >+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); >+ >+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(PLATFORM_NAME)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); >+MACOSX_DEPLOYMENT_TARGET_macosx_101000 = 10.10; >+MACOSX_DEPLOYMENT_TARGET_macosx_101100 = 10.11; >+MACOSX_DEPLOYMENT_TARGET_macosx_101200 = 10.12; >+MACOSX_DEPLOYMENT_TARGET_macosx_101300 = 10.13; >+ >+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; >+DEBUG_INFORMATION_FORMAT = dwarf; >+ >+SDKROOT = $(SDKROOT_$(USE_INTERNAL_SDK)); >+SDKROOT_ = macosx; >+SDKROOT_YES = macosx.internal; >diff --git a/Tools/lldb/lldbWebKitTester/Configurations/lldbWebKitTester.xcconfig b/Tools/lldb/lldbWebKitTester/Configurations/lldbWebKitTester.xcconfig >new file mode 100644 >index 0000000000000000000000000000000000000000..0666000d1afdd7dd1ce5ffc1b2d1fe10523d5e3e >--- /dev/null >+++ b/Tools/lldb/lldbWebKitTester/Configurations/lldbWebKitTester.xcconfig >@@ -0,0 +1,24 @@ >+// Copyright (C) 2015-2018 Apple Inc. All rights reserved. >+// >+// Redistribution and use in source and binary forms, with or without >+// modification, are permitted provided that the following conditions >+// are met: >+// 1. Redistributions of source code must retain the above copyright >+// notice, this list of conditions and the following disclaimer. >+// 2. 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. >+// >+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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. >+ >+PRODUCT_NAME = $(TARGET_NAME); >diff --git a/Tools/lldb/lldbWebKitTester/Makefile b/Tools/lldb/lldbWebKitTester/Makefile >new file mode 100644 >index 0000000000000000000000000000000000000000..058c21e1ba387a8ba4fc43f1444c380eec79ede9 >--- /dev/null >+++ b/Tools/lldb/lldbWebKitTester/Makefile >@@ -0,0 +1,2 @@ >+SCRIPTS_PATH = ../../Scripts >+include ../../../Makefile.shared >diff --git a/Tools/lldb/lldbWebKitTester/lldbWebKitTester.xcodeproj/project.pbxproj b/Tools/lldb/lldbWebKitTester/lldbWebKitTester.xcodeproj/project.pbxproj >new file mode 100644 >index 0000000000000000000000000000000000000000..4d34748c75ecf51747397e1e5a5c70b890c70500 >--- /dev/null >+++ b/Tools/lldb/lldbWebKitTester/lldbWebKitTester.xcodeproj/project.pbxproj >@@ -0,0 +1,202 @@ >+// !$*UTF8*$! >+{ >+ archiveVersion = 1; >+ classes = { >+ }; >+ objectVersion = 46; >+ objects = { >+ >+/* Begin PBXBuildFile section */ >+ 7CB6844B1AFA7978002B305C /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CB6844A1AFA7978002B305C /* main.cpp */; }; >+ CE3F4426205C6A01007195B3 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE3F4422205C669C007195B3 /* JavaScriptCore.framework */; }; >+/* End PBXBuildFile section */ >+ >+/* Begin PBXCopyFilesBuildPhase section */ >+ 7C4AB39F1AF0276C003FC8D1 /* CopyFiles */ = { >+ isa = PBXCopyFilesBuildPhase; >+ buildActionMask = 2147483647; >+ dstPath = /usr/share/man/man1/; >+ dstSubfolderSpec = 0; >+ files = ( >+ ); >+ runOnlyForDeploymentPostprocessing = 1; >+ }; >+/* End PBXCopyFilesBuildPhase section */ >+ >+/* Begin PBXFileReference section */ >+ 7C2227511AFC4D9C008C3338 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; }; >+ 7C2227521AFC4D9C008C3338 /* lldbWebKitTester.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lldbWebKitTester.xcconfig; sourceTree = "<group>"; }; >+ 7C2227531AFC4D9C008C3338 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; }; >+ 7C4AB3A11AF0276C003FC8D1 /* lldbWebKitTester */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lldbWebKitTester; sourceTree = BUILT_PRODUCTS_DIR; }; >+ 7CB6844A1AFA7978002B305C /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = SOURCE_ROOT; }; >+ CE3F4422205C669C007195B3 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; >+/* End PBXFileReference section */ >+ >+/* Begin PBXFrameworksBuildPhase section */ >+ 7C4AB39E1AF0276C003FC8D1 /* Frameworks */ = { >+ isa = PBXFrameworksBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ CE3F4426205C6A01007195B3 /* JavaScriptCore.framework in Frameworks */, >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+/* End PBXFrameworksBuildPhase section */ >+ >+/* Begin PBXGroup section */ >+ 7C2227501AFC4D0A008C3338 /* Configurations */ = { >+ isa = PBXGroup; >+ children = ( >+ 7C2227511AFC4D9C008C3338 /* Base.xcconfig */, >+ 7C2227531AFC4D9C008C3338 /* DebugRelease.xcconfig */, >+ 7C2227521AFC4D9C008C3338 /* lldbWebKitTester.xcconfig */, >+ ); >+ path = Configurations; >+ sourceTree = "<group>"; >+ }; >+ 7C4AB3981AF0276C003FC8D1 = { >+ isa = PBXGroup; >+ children = ( >+ 7C2227501AFC4D0A008C3338 /* Configurations */, >+ CE3F4425205C6A01007195B3 /* Frameworks */, >+ CE3F4424205C66D9007195B3 /* lldbWebKitTester */, >+ 7C4AB3A21AF0276C003FC8D1 /* Products */, >+ CE3F4422205C669C007195B3 /* JavaScriptCore.framework */, >+ ); >+ sourceTree = "<group>"; >+ }; >+ 7C4AB3A21AF0276C003FC8D1 /* Products */ = { >+ isa = PBXGroup; >+ children = ( >+ 7C4AB3A11AF0276C003FC8D1 /* lldbWebKitTester */, >+ ); >+ name = Products; >+ sourceTree = "<group>"; >+ }; >+ CE3F4424205C66D9007195B3 /* lldbWebKitTester */ = { >+ isa = PBXGroup; >+ children = ( >+ 7CB6844A1AFA7978002B305C /* main.cpp */, >+ ); >+ name = lldbWebKitTester; >+ sourceTree = "<group>"; >+ }; >+ CE3F4425205C6A01007195B3 /* Frameworks */ = { >+ isa = PBXGroup; >+ children = ( >+ ); >+ name = Frameworks; >+ sourceTree = "<group>"; >+ }; >+/* End PBXGroup section */ >+ >+/* Begin PBXNativeTarget section */ >+ 7C4AB3A01AF0276C003FC8D1 /* lldbWebKitTester */ = { >+ isa = PBXNativeTarget; >+ buildConfigurationList = 7C4AB3A81AF0276C003FC8D1 /* Build configuration list for PBXNativeTarget "lldbWebKitTester" */; >+ buildPhases = ( >+ 7C4AB39D1AF0276C003FC8D1 /* Sources */, >+ 7C4AB39E1AF0276C003FC8D1 /* Frameworks */, >+ 7C4AB39F1AF0276C003FC8D1 /* CopyFiles */, >+ ); >+ buildRules = ( >+ ); >+ dependencies = ( >+ ); >+ name = lldbWebKitTester; >+ productName = lldbWebKitTester; >+ productReference = 7C4AB3A11AF0276C003FC8D1 /* lldbWebKitTester */; >+ productType = "com.apple.product-type.tool"; >+ }; >+/* End PBXNativeTarget section */ >+ >+/* Begin PBXProject section */ >+ 7C4AB3991AF0276C003FC8D1 /* Project object */ = { >+ isa = PBXProject; >+ attributes = { >+ LastUpgradeCheck = 0700; >+ }; >+ buildConfigurationList = 7C4AB39C1AF0276C003FC8D1 /* Build configuration list for PBXProject "lldbWebKitTester" */; >+ compatibilityVersion = "Xcode 3.2"; >+ developmentRegion = English; >+ hasScannedForEncodings = 0; >+ knownRegions = ( >+ en, >+ ); >+ mainGroup = 7C4AB3981AF0276C003FC8D1; >+ productRefGroup = 7C4AB3A21AF0276C003FC8D1 /* Products */; >+ projectDirPath = ""; >+ projectRoot = ""; >+ targets = ( >+ 7C4AB3A01AF0276C003FC8D1 /* lldbWebKitTester */, >+ ); >+ }; >+/* End PBXProject section */ >+ >+/* Begin PBXSourcesBuildPhase section */ >+ 7C4AB39D1AF0276C003FC8D1 /* Sources */ = { >+ isa = PBXSourcesBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ 7CB6844B1AFA7978002B305C /* main.cpp in Sources */, >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+/* End PBXSourcesBuildPhase section */ >+ >+/* Begin XCBuildConfiguration section */ >+ 7C4AB3A61AF0276C003FC8D1 /* Debug */ = { >+ isa = XCBuildConfiguration; >+ baseConfigurationReference = 7C2227531AFC4D9C008C3338 /* DebugRelease.xcconfig */; >+ buildSettings = { >+ DEBUG_DEFINES = "$(DEBUG_DEFINES_debug)"; >+ GCC_OPTIMIZATION_LEVEL = "$(GCC_OPTIMIZATION_LEVEL_debug)"; >+ }; >+ name = Debug; >+ }; >+ 7C4AB3A71AF0276C003FC8D1 /* Release */ = { >+ isa = XCBuildConfiguration; >+ baseConfigurationReference = 7C2227531AFC4D9C008C3338 /* DebugRelease.xcconfig */; >+ buildSettings = { >+ }; >+ name = Release; >+ }; >+ 7C4AB3A91AF0276C003FC8D1 /* Debug */ = { >+ isa = XCBuildConfiguration; >+ baseConfigurationReference = 7C2227521AFC4D9C008C3338 /* lldbWebKitTester.xcconfig */; >+ buildSettings = { >+ }; >+ name = Debug; >+ }; >+ 7C4AB3AA1AF0276C003FC8D1 /* Release */ = { >+ isa = XCBuildConfiguration; >+ baseConfigurationReference = 7C2227521AFC4D9C008C3338 /* lldbWebKitTester.xcconfig */; >+ buildSettings = { >+ }; >+ name = Release; >+ }; >+/* End XCBuildConfiguration section */ >+ >+/* Begin XCConfigurationList section */ >+ 7C4AB39C1AF0276C003FC8D1 /* Build configuration list for PBXProject "lldbWebKitTester" */ = { >+ isa = XCConfigurationList; >+ buildConfigurations = ( >+ 7C4AB3A61AF0276C003FC8D1 /* Debug */, >+ 7C4AB3A71AF0276C003FC8D1 /* Release */, >+ ); >+ defaultConfigurationIsVisible = 0; >+ defaultConfigurationName = Release; >+ }; >+ 7C4AB3A81AF0276C003FC8D1 /* Build configuration list for PBXNativeTarget "lldbWebKitTester" */ = { >+ isa = XCConfigurationList; >+ buildConfigurations = ( >+ 7C4AB3A91AF0276C003FC8D1 /* Debug */, >+ 7C4AB3AA1AF0276C003FC8D1 /* Release */, >+ ); >+ defaultConfigurationIsVisible = 0; >+ defaultConfigurationName = Release; >+ }; >+/* End XCConfigurationList section */ >+ }; >+ rootObject = 7C4AB3991AF0276C003FC8D1 /* Project object */; >+} >diff --git a/Tools/lldb/lldbWebKitTester/main.cpp b/Tools/lldb/lldbWebKitTester/main.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..bea464e48cc19b261fbb75e2f7dfa84c3b4a7989 >--- /dev/null >+++ b/Tools/lldb/lldbWebKitTester/main.cpp >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. 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. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 <iostream> >+#include <wtf/text/StringBuilder.h> >+#include <wtf/text/WTFString.h> >+ >+extern void breakForTestingSummaryProviders(); >+void breakForTestingSummaryProviders() { return; } >+ >+// From Tools/TestWebKitAPI/WTFStringUtilities.h >+template<size_t length> >+static String utf16String(const char16_t (&string)[length]) >+{ >+ StringBuilder builder; >+ builder.reserveCapacity(length - 1); >+ for (auto c : string) >+ builder.append(static_cast<UChar>(c)); >+ return builder.toString(); >+} >+ >+static void testSummaryProviders() >+{ >+ String aNullString { "" }; >+ StringImpl* aNullStringImpl = aNullString.impl(); >+ >+ String anEmptyString { "" }; >+ StringImpl* anEmptyStringImpl = anEmptyString.impl(); >+ >+ String an8BitString { "résumé" }; >+ StringImpl* an8BitStringImpl = an8BitString.impl(); >+ >+ String a16BitString = utf16String(u"\u1680Cappuccino\u1680"); >+ StringImpl* a16BitStringImpl = a16BitString.impl(); >+ >+ breakForTestingSummaryProviders(); >+} >+ >+int main(int argc, const char* argv[]) >+{ >+ testSummaryProviders(); >+ std::cerr << "This executable does nothing and is only meant for debugging lldb_webkit.py." << std::endl; >+ return 0; >+} >diff --git a/Tools/lldb/lldb_webkit_unittest.py b/Tools/lldb/lldb_webkit_unittest.py >new file mode 100755 >index 0000000000000000000000000000000000000000..c1bd0253569ea6d4f954211be7f45f5919f52b74 >--- /dev/null >+++ b/Tools/lldb/lldb_webkit_unittest.py >@@ -0,0 +1,140 @@ >+#!/usr/bin/env python >+# -*- coding: utf-8 -*- >+# >+# Copyright (C) 2018 Apple Inc. All rights reserved. >+# >+# Redistribution and use in source and binary forms, with or without >+# modification, are permitted provided that the following conditions >+# are met: >+# 1. Redistributions of source code must retain the above copyright >+# notice, this list of conditions and the following disclaimer. >+# 2. 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. >+# >+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. >+ >+import atexit >+import lldb >+import lldb_webkit >+import os >+import sys >+import unittest >+ >+from webkitpy.common.system.systemhost import SystemHost >+from webkitpy.port.config import Config >+ >+ >+# We cache the lldb debug session state so that we don't create it again for each call to a serial_test_ method. >+# We store it in a global variable so that we can delete this cached state on exit(3). >+# FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule() >+# are called exactly once per class/module). >+cached_debug_session = None >+ >+ >+# FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule() >+# are called exactly once per class/module). >+@atexit.register >+def destroy_cached_debug_session(): >+ if cached_debug_session: >+ cached_debug_session.tearDown() >+ >+ >+class LLDBDebugSession(object): >+ @classmethod >+ def setup(cls): >+ LLDB_WEBKIT_TESTER_NAME = 'lldbWebKitTester' >+ BREAK_FOR_TESTING_FUNCTION_NAME = 'breakForTestingSummaryProviders' >+ >+ cls.sbDebugger = lldb.SBDebugger.Create() >+ cls.sbDebugger.SetAsync(False) >+ >+ host = SystemHost() >+ config = Config(host.executive, host.filesystem) >+ cls.lldbWebKitTesterExecutable = host.filesystem.join(config.build_directory('Debug'), LLDB_WEBKIT_TESTER_NAME) >+ >+ cls.sbTarget = cls.sbDebugger.CreateTargetWithFileAndArch(str(cls.lldbWebKitTesterExecutable), lldb.LLDB_ARCH_DEFAULT) >+ assert cls.sbTarget >+ cls.sbTarget.BreakpointCreateByName(BREAK_FOR_TESTING_FUNCTION_NAME, cls.sbTarget.GetExecutable().GetFilename()) >+ >+ argv = None >+ envp = None >+ cls.sbProcess = cls.sbTarget.LaunchSimple(argv, envp, os.getcwd()) >+ assert cls.sbProcess >+ assert cls.sbProcess.GetState() == lldb.eStateStopped >+ >+ cls.sbThread = cls.sbProcess.GetThreadAtIndex(0) >+ assert cls.sbThread >+ >+ # Frame 0 is the function with name BREAK_FOR_TESTING_FUNCTION_NAME. We want the frame of the caller of >+ # BREAK_FOR_TESTING_FUNCTION_NAME because it has all the interesting local variables we want to test. >+ cls.sbFrame = cls.sbThread.GetFrameAtIndex(1) >+ assert cls.sbFrame >+ >+ @classmethod >+ def tearDown(cls): >+ cls.sbProcess.Kill() >+ cls.sbTarget.DeleteAllBreakpoints() >+ >+ >+class TestSummaryProviders(unittest.TestCase): >+ @classmethod >+ def setUpClass(cls): >+ global cached_debug_session >+ if not cached_debug_session: >+ cached_debug_session = LLDBDebugSession() >+ cached_debug_session.setup() >+ >+ @property >+ def _sbFrame(self): >+ return cached_debug_session.sbFrame >+ >+ # The LLDB Python module does not work with Python multiprocessing and causes errors of the form: >+ # objc[76794]: +[__MDQuery initialize] may have been in progress in another thread when fork() was called. >+ # We cannot safely call it or ignore it in the fork() child process. Crashing instead. >+ # So, we run the following tests serially. >+ >+ # MARK: WTFStringImpl_SummaryProvider test cases >+ >+ def serial_test_WTFStringImpl_SummaryProvider_null_string(self): >+ summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('aNullStringImpl'), {}) >+ self.assertEqual(summary, "{ length = 0, is8bit = 1, contents = '' }") >+ >+ def serial_test_WTFStringImpl_SummaryProvider_empty_string(self): >+ summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('anEmptyStringImpl'), {}) >+ self.assertEqual(summary, "{ length = 0, is8bit = 1, contents = '' }") >+ >+ def serial_test_WTFStringImpl_SummaryProvider_8bit_string(self): >+ summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('an8BitStringImpl'), {}) >+ self.assertEqual(summary, "{ length = 8, is8bit = 1, contents = 'r\\xe9sum\\xe9' }") >+ >+ def serial_test_WTFStringImpl_SummaryProvider_16bit_string(self): >+ summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('a16BitStringImpl'), {}) >+ self.assertEqual(summary, u"{ length = 13, is8bit = 0, contents = '\\u1680Cappuccino\\u1680\\x00' }") >+ >+ # MARK: WTFString_SummaryProvider test cases >+ >+ def serial_test_WTFString_SummaryProvider_null_string(self): >+ summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('aNullString'), {}) >+ self.assertEqual(summary, "{ length = 0, contents = '' }") >+ >+ def serial_test_WTFString_SummaryProvider_empty_string(self): >+ summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('anEmptyString'), {}) >+ self.assertEqual(summary, "{ length = 0, contents = '' }") >+ >+ def serial_test_WTFString_SummaryProvider_8bit_string(self): >+ summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('an8BitString'), {}) >+ self.assertEqual(summary, "{ length = 8, contents = 'r\\xe9sum\\xe9' }") >+ >+ def serial_test_WTFString_SummaryProvider_16bit_string(self): >+ summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('a16BitString'), {}) >+ self.assertEqual(summary, u"{ length = 13, contents = '\\u1680Cappuccino\\u1680\\x00' }")
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 183744
:
336054
|
336055
|
336057
|
340870
|
340913
|
341110
|
341210
|
341388
|
341691
|
341712
|
341714
|
341716
|
341731
|
341733
|
341791
|
341794
|
343791