diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/api')
15 files changed, 198 insertions, 91 deletions
| diff --git a/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py b/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py index 0ed2df3ceab1..dd6dbe0a37ed 100644 --- a/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py +++ b/packages/Python/lldbsuite/test/api/check_public_api_headers/TestPublicAPIHeaders.py @@ -6,21 +6,22 @@ should compile and link with the LLDB framework."""  from __future__ import print_function - -import os, re +import os +import re  from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import *  from lldbsuite.test import lldbutil +  class SBDirCheckerCase(TestBase):      mydir = TestBase.compute_mydir(__file__)      def setUp(self):          TestBase.setUp(self) -        self.template = 'main.cpp.template'          self.source = 'main.cpp'          self.exe_name = 'a.out' +        self.generateSource(self.source)      @skipIfNoSBHeaders      def test_sb_api_directory(self): @@ -30,60 +31,38 @@ class SBDirCheckerCase(TestBase):          if not (self.platformIsDarwin() and self.getArchitecture() == "x86_64"):              self.skipTest("This test is only for LLDB.framework built 64-bit")          if self.getArchitecture() == "i386": -            self.skipTest("LLDB is 64-bit and cannot be linked to 32-bit test program.") +            self.skipTest( +                "LLDB is 64-bit and cannot be linked to 32-bit test program.") -        # Generate main.cpp, build it, and execute. -        self.generate_main_cpp()          self.buildDriver(self.source, self.exe_name)          self.sanity_check_executable(self.exe_name) -    def generate_main_cpp(self): -        """Generate main.cpp from main.cpp.template.""" -        temp = os.path.join(os.getcwd(), self.template) -        with open(temp, 'r') as f: -            content = f.read() - -        public_api_dir = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API") - -        # Look under the include/lldb/API directory and add #include statements -        # for all the SB API headers. -        public_headers = os.listdir(public_api_dir) -        # For different platforms, the include statement can vary. -        if self.platformIsDarwin(): -            include_stmt = "'#include <%s>' % os.path.join('LLDB', header)" -        if self.getPlatform() == "freebsd" or self.getPlatform() == "linux" or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile': -            include_stmt = "'#include <%s>' % os.path.join(public_api_dir, header)" -        list = [eval(include_stmt) for header in public_headers if (header.startswith("SB") and -                                                                    header.endswith(".h"))] -        includes = '\n'.join(list) -        new_content = content.replace('%include_SB_APIs%', includes) -        src = os.path.join(os.getcwd(), self.source) -        with open(src, 'w') as f: -            f.write(new_content) - -        # The main.cpp has been generated, add a teardown hook to remove it. -        self.addTearDownHook(lambda: os.remove(src)) -      def sanity_check_executable(self, exe_name):          """Sanity check executable compiled from the auto-generated program."""          exe = os.path.join(os.getcwd(), exe_name)          self.runCmd("file %s" % exe, CURRENT_EXECUTABLE_SET) -        self.line_to_break = line_number(self.source, '// Set breakpoint here.') +        self.line_to_break = line_number( +            self.source, '// Set breakpoint here.') -        env_cmd = "settings set target.env-vars %s=%s" %(self.dylibPath, self.getLLDBLibraryEnvVal()) +        env_cmd = "settings set target.env-vars %s=%s" % ( +            self.dylibPath, self.getLLDBLibraryEnvVal())          if self.TraceOn():              print("Set environment to: ", env_cmd)          self.runCmd(env_cmd) -        self.addTearDownHook(lambda: self.dbg.HandleCommand("settings remove target.env-vars %s" % self.dylibPath)) +        self.addTearDownHook( +            lambda: self.dbg.HandleCommand( +                "settings remove target.env-vars %s" % +                self.dylibPath)) -        lldbutil.run_break_set_by_file_and_line (self, self.source, self.line_to_break, num_expected_locations = -1) +        lldbutil.run_break_set_by_file_and_line( +            self, self.source, self.line_to_break, num_expected_locations=-1)          self.runCmd("run", RUN_SUCCEEDED)          # The stop reason of the thread should be breakpoint.          self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, -            substrs = ['stopped', -                       'stop reason = breakpoint']) +                    substrs=['stopped', +                             'stop reason = breakpoint'])          self.runCmd('frame variable') diff --git a/packages/Python/lldbsuite/test/api/listeners/TestListener.py b/packages/Python/lldbsuite/test/api/listeners/TestListener.py index bd8c204e78cb..65232f014102 100644 --- a/packages/Python/lldbsuite/test/api/listeners/TestListener.py +++ b/packages/Python/lldbsuite/test/api/listeners/TestListener.py @@ -15,6 +15,7 @@ from lldbsuite.test import lldbutil  import six +  class ListenToModuleLoadedEvents (TestBase):      mydir = TestBase.compute_mydir(__file__) @@ -24,14 +25,17 @@ class ListenToModuleLoadedEvents (TestBase):          TestBase.setUp(self)          self.build() -    def test_receiving_breakpoint_added (self): +    def test_receiving_breakpoint_added(self):          """Test that we get breakpoint added events, waiting on event classes on the debugger"""          my_listener = lldb.SBListener("test_listener") -         -        my_listener.StartListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged) -        exe = os.path.join (os.getcwd(), "a.out") +        my_listener.StartListeningForEventClass( +            self.dbg, +            lldb.SBTarget.GetBroadcasterClassName(), +            lldb.SBTarget.eBroadcastBitBreakpointChanged) + +        exe = os.path.join(os.getcwd(), "a.out")          target = self.dbg.CreateTarget(exe) @@ -39,17 +43,29 @@ class ListenToModuleLoadedEvents (TestBase):          event = lldb.SBEvent()          my_listener.WaitForEvent(1, event) -         +          self.assertTrue(event.IsValid(), "Got a valid event.") -        self.assertTrue(lldb.SBBreakpoint.EventIsBreakpointEvent(event), "It is a breakpoint event.") -        self.assertTrue(lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event) == lldb.eBreakpointEventTypeAdded, "It is a breakpoint added event.") -        self.assertTrue(bkpt == lldb.SBBreakpoint.GetBreakpointFromEvent(event), "It is our breakpoint.") +        self.assertTrue( +            lldb.SBBreakpoint.EventIsBreakpointEvent(event), +            "It is a breakpoint event.") +        self.assertTrue(lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent( +            event) == lldb.eBreakpointEventTypeAdded, "It is a breakpoint added event.") +        self.assertTrue( +            bkpt == lldb.SBBreakpoint.GetBreakpointFromEvent(event), +            "It is our breakpoint.")          # Now make sure if we stop listening for events we don't get them: -        my_listener.StopListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged) -        my_listener.StopListeningForEvents(target.GetBroadcaster(), lldb.SBTarget.eBroadcastBitBreakpointChanged) +        my_listener.StopListeningForEventClass( +            self.dbg, +            lldb.SBTarget.GetBroadcasterClassName(), +            lldb.SBTarget.eBroadcastBitBreakpointChanged) +        my_listener.StopListeningForEvents( +            target.GetBroadcaster(), +            lldb.SBTarget.eBroadcastBitBreakpointChanged)          bkpt2 = target.BreakpointCreateByName("main")          my_listener.WaitForEvent(1, event) -        self.assertTrue(not event.IsValid(), "We don't get events we aren't listening to.") +        self.assertTrue( +            not event.IsValid(), +            "We don't get events we aren't listening to.") diff --git a/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py b/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py index ca2b986ce740..20e41f0f4121 100644 --- a/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py +++ b/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py @@ -3,8 +3,8 @@  from __future__ import print_function - -import os, re +import os +import re  import subprocess  import lldb @@ -12,16 +12,23 @@ from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import *  from lldbsuite.test import lldbutil +  class TestMultipleSimultaneousDebuggers(TestBase):      mydir = TestBase.compute_mydir(__file__)      @skipIfNoSBHeaders -    @expectedFlakeyDarwin() -    @expectedFailureAll(archs="i[3-6]86", bugnumber="multi-process-driver.cpp creates an x64 target") -    @expectedFailureAll(oslist=["windows", "linux", "freebsd"], bugnumber="llvm.org/pr20282") +    @expectedFailureAll( +        archs="i[3-6]86", +        bugnumber="multi-process-driver.cpp creates an x64 target") +    @expectedFailureAll( +        oslist=[ +            "windows", +            "linux", +            "freebsd"], +        bugnumber="llvm.org/pr20282")      def test_multiple_debuggers(self): -        env = {self.dylibPath : self.getLLDBLibraryEnvVal()} +        env = {self.dylibPath: self.getLLDBLibraryEnvVal()}          self.driver_exe = os.path.join(os.getcwd(), "multi-process-driver")          self.buildDriver('multi-process-driver.cpp', self.driver_exe) @@ -41,4 +48,5 @@ class TestMultipleSimultaneousDebuggers(TestBase):              check_call([self.driver_exe, self.inferior_exe], env=env)          else:              with open(os.devnull, 'w') as fnull: -                check_call([self.driver_exe, self.inferior_exe], env=env, stdout=fnull, stderr=fnull) +                check_call([self.driver_exe, self.inferior_exe], +                           env=env, stdout=fnull, stderr=fnull) diff --git a/packages/Python/lldbsuite/test/api/multiple-debuggers/multi-process-driver.cpp b/packages/Python/lldbsuite/test/api/multiple-debuggers/multi-process-driver.cpp index 1c2689ff6c4f..448304d83c75 100644 --- a/packages/Python/lldbsuite/test/api/multiple-debuggers/multi-process-driver.cpp +++ b/packages/Python/lldbsuite/test/api/multiple-debuggers/multi-process-driver.cpp @@ -25,7 +25,7 @@  #include <chrono>  #include <thread> -#define NUMBER_OF_SIMULTANEOUS_DEBUG_SESSIONS 20 +#define NUMBER_OF_SIMULTANEOUS_DEBUG_SESSIONS 10  #define DEBUG 0 diff --git a/packages/Python/lldbsuite/test/api/multiple-targets/Makefile b/packages/Python/lldbsuite/test/api/multiple-targets/Makefile new file mode 100644 index 000000000000..bee559c8ecdd --- /dev/null +++ b/packages/Python/lldbsuite/test/api/multiple-targets/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../make + +MAKE_DSYM := NO + +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/api/multiple-targets/TestMultipleTargets.py b/packages/Python/lldbsuite/test/api/multiple-targets/TestMultipleTargets.py new file mode 100644 index 000000000000..decb3fd4f0c5 --- /dev/null +++ b/packages/Python/lldbsuite/test/api/multiple-targets/TestMultipleTargets.py @@ -0,0 +1,44 @@ +"""Test the lldb public C++ api when creating multiple targets simultaneously.""" + +from __future__ import print_function + + +import os +import re +import subprocess + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestMultipleTargets(TestBase): + +    mydir = TestBase.compute_mydir(__file__) +    NO_DEBUG_INFO_TESTCASE = True + +    @skipIfNoSBHeaders +    @skipIfHostIncompatibleWithRemote +    @expectedFailureAll( +        oslist=["windows", "freebsd"], +        bugnumber="llvm.org/pr20282") +    def test_multiple_targets(self): +        env = {self.dylibPath: self.getLLDBLibraryEnvVal()} + +        self.driver_exe = os.path.join(os.getcwd(), "multi-target") +        self.buildDriver('main.cpp', self.driver_exe) +        self.addTearDownHook(lambda: os.remove(self.driver_exe)) +        self.signBinary(self.driver_exe) + +# check_call will raise a CalledProcessError if multi-process-driver doesn't return +# exit code 0 to indicate success.  We can let this exception go - the test harness +# will recognize it as a test failure. + +        if self.TraceOn(): +            print("Running test %s" % self.driver_exe) +            check_call([self.driver_exe, self.driver_exe], env=env) +        else: +            with open(os.devnull, 'w') as fnull: +                check_call([self.driver_exe, self.driver_exe], +                           env=env, stdout=fnull, stderr=fnull) diff --git a/packages/Python/lldbsuite/test/api/multiple-targets/main.cpp b/packages/Python/lldbsuite/test/api/multiple-targets/main.cpp new file mode 100644 index 000000000000..35fb4e0d613e --- /dev/null +++ b/packages/Python/lldbsuite/test/api/multiple-targets/main.cpp @@ -0,0 +1,31 @@ +#include <thread> + +#include "lldb/API/LLDB.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBTarget.h" + +using namespace lldb; +int main (int argc, char **argv) +{ +  // We are expecting the program path and a path to an executable to load +  if (argc != 2) +    return 1; +  const char *program_file = argv[1]; +  SBDebugger::Initialize(); +  SBDebugger debugger = SBDebugger::Create(false); +  auto lambda = [&](){ +    SBError error; +    SBTarget target = debugger.CreateTarget(program_file, nullptr, nullptr,  +                                            false, error); +  }; + +  // Create 3 targets at the same time and make sure we don't crash. +  std::thread thread1(lambda); +  std::thread thread2(lambda); +  std::thread thread3(lambda); +  thread1.join(); +  thread2.join(); +  thread3.join(); +  SBDebugger::Terminate(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py b/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py index 7959bb73de02..0d6a6002d522 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py +++ b/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py @@ -5,19 +5,31 @@ from __future__ import print_function  # __package__ = "lldbsuite.test" -import os, re +import os +import re  from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import *  from lldbsuite.test import lldbutil  import subprocess +  class SBBreakpointCallbackCase(TestBase): +    def setUp(self): +        TestBase.setUp(self) +        self.generateSource('driver.cpp') +        self.generateSource('listener_test.cpp') +        self.generateSource('test_breakpoint_callback.cpp') +        self.generateSource('test_listener_event_description.cpp') +        self.generateSource('test_listener_event_process_state.cpp') +        self.generateSource('test_listener_resume.cpp') +      mydir = TestBase.compute_mydir(__file__)      @skipIfRemote      @skipIfNoSBHeaders -    @skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538) +    # clang-cl does not support throw or catch (llvm.org/pr24538) +    @skipIfWindows      def test_breakpoint_callback(self):          """Test the that SBBreakpoint callback is invoked when a breakpoint is hit. """          self.build_and_test('driver.cpp test_breakpoint_callback.cpp', @@ -25,40 +37,44 @@ class SBBreakpointCallbackCase(TestBase):      @skipIfRemote      @skipIfNoSBHeaders -    @skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538) +    # clang-cl does not support throw or catch (llvm.org/pr24538) +    @skipIfWindows      @expectedFlakeyFreeBSD      def test_sb_api_listener_event_description(self):          """ Test the description of an SBListener breakpoint event is valid.""" -        self.build_and_test('driver.cpp listener_test.cpp test_listener_event_description.cpp', -                            'test_listener_event_description') +        self.build_and_test( +            'driver.cpp listener_test.cpp test_listener_event_description.cpp', +            'test_listener_event_description')          pass      @skipIfRemote      @skipIfNoSBHeaders -    @skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538) +    # clang-cl does not support throw or catch (llvm.org/pr24538) +    @skipIfWindows      @expectedFlakeyFreeBSD -    @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["x86_64"])      def test_sb_api_listener_event_process_state(self):          """ Test that a registered SBListener receives events when a process              changes state.          """ -        self.build_and_test('driver.cpp listener_test.cpp test_listener_event_process_state.cpp', -                            'test_listener_event_process_state') +        self.build_and_test( +            'driver.cpp listener_test.cpp test_listener_event_process_state.cpp', +            'test_listener_event_process_state')          pass -      @skipIfRemote      @skipIfNoSBHeaders -    @skipIfWindows # clang-cl does not support throw or catch (llvm.org/pr24538) +    # clang-cl does not support throw or catch (llvm.org/pr24538) +    @skipIfWindows      @expectedFlakeyFreeBSD      @expectedFailureAll(oslist=["linux"])      def test_sb_api_listener_resume(self):          """ Test that a process can be resumed from a non-main thread. """ -        self.build_and_test('driver.cpp listener_test.cpp test_listener_resume.cpp', -                            'test_listener_resume') +        self.build_and_test( +            'driver.cpp listener_test.cpp test_listener_resume.cpp', +            'test_listener_resume')          pass -    def build_and_test(self, sources, test_name, args = None): +    def build_and_test(self, sources, test_name, args=None):          """ Build LLDB test from sources, and run expecting 0 exit code """          # These tests link against host lldb API. @@ -66,7 +82,8 @@ class SBBreakpointCallbackCase(TestBase):          # because remote is disabled, we can assume that the os is the same          # still need to check architecture          if self.getLldbArchitecture() != self.getArchitecture(): -            self.skipTest("This test is only run if the target arch is the same as the lldb binary arch") +            self.skipTest( +                "This test is only run if the target arch is the same as the lldb binary arch")          self.inferior = 'inferior_program'          self.buildProgram('inferior.cpp', self.inferior) @@ -79,7 +96,7 @@ class SBBreakpointCallbackCase(TestBase):          self.signBinary(test_exe)          exe = [test_exe, self.inferior] -        env = {self.dylibPath : self.getLLDBLibraryEnvVal()} +        env = {self.dylibPath: self.getLLDBLibraryEnvVal()}          if self.TraceOn():              print("Running test %s" % " ".join(exe))              check_call(exe, env=env) diff --git a/packages/Python/lldbsuite/test/api/multithreaded/driver.cpp b/packages/Python/lldbsuite/test/api/multithreaded/driver.cpp.template index fa0c48e0ecfb..f4bd021632ce 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/driver.cpp +++ b/packages/Python/lldbsuite/test/api/multithreaded/driver.cpp.template @@ -6,8 +6,11 @@  #include <iterator>  #include <string>  #include <vector> +#if !defined(_MSC_VER) +  #include <signal.h> +#endif -#include "lldb-headers.h" +%include_SB_APIs%  #include "common.h" @@ -17,6 +20,13 @@ using namespace lldb;  void test(SBDebugger &dbg, std::vector<string> args);  int main(int argc, char** argv) { + +// Ignore SIGPIPE.  The lldb driver does this as well, +// because we seem to get spurious SIGPIPES on some +// Unixen that take the driver down. +#if !defined(_MSC_VER) +  signal(SIGPIPE, SIG_IGN); +#endif    int code = 0;    SBDebugger::Initialize(); diff --git a/packages/Python/lldbsuite/test/api/multithreaded/listener_test.cpp b/packages/Python/lldbsuite/test/api/multithreaded/listener_test.cpp.template index b20868ff94f4..e305d1af4893 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/listener_test.cpp +++ b/packages/Python/lldbsuite/test/api/multithreaded/listener_test.cpp.template @@ -7,7 +7,7 @@  #include <thread>  #include <vector> -#include "lldb-headers.h" +%include_SB_APIs%  #include "common.h"  using namespace lldb; diff --git a/packages/Python/lldbsuite/test/api/multithreaded/lldb-headers.h b/packages/Python/lldbsuite/test/api/multithreaded/lldb-headers.h deleted file mode 100644 index da0914b3b071..000000000000 --- a/packages/Python/lldbsuite/test/api/multithreaded/lldb-headers.h +++ /dev/null @@ -1,11 +0,0 @@ - -#ifndef LLDB_HEADERS_H -#define LLDB_HEADERS_H - -#ifdef __APPLE__ -#include <LLDB/LLDB.h> -#else -#include "lldb/API/LLDB.h" -#endif - -#endif // LLDB_HEADERS_H diff --git a/packages/Python/lldbsuite/test/api/multithreaded/test_breakpoint_callback.cpp b/packages/Python/lldbsuite/test/api/multithreaded/test_breakpoint_callback.cpp.template index def31f82b0c7..4133025aa495 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/test_breakpoint_callback.cpp +++ b/packages/Python/lldbsuite/test/api/multithreaded/test_breakpoint_callback.cpp.template @@ -7,7 +7,7 @@  #include <vector>  #include <string> -#include "lldb-headers.h" +%include_SB_APIs%  #include "common.h" diff --git a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_description.cpp b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_description.cpp.template index 0d7844dce6d0..63e3f3631e5d 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_description.cpp +++ b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_description.cpp.template @@ -8,7 +8,7 @@  #include <string>  #include <thread> -#include "lldb-headers.h" +%include_SB_APIs%  #include "common.h" diff --git a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp.template index a79c5cb2a08b..2926ece4d8d9 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp +++ b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp.template @@ -8,7 +8,7 @@  #include <string>  #include <thread> -#include "lldb-headers.h" +%include_SB_APIs%  #include "common.h" @@ -31,6 +31,11 @@ void listener_func() {          throw Exception("event is not valid in listener thread");          // send process description          SBProcess process = SBProcess::GetProcessFromEvent(event); +        if (!process.IsValid()) +            throw Exception("process is not valid"); +        if (SBProcess::GetStateFromEvent(event) != lldb::eStateStopped || SBProcess::GetRestartedFromEvent(event)) +            continue; // Only interested in "stopped" events. +          SBStream description;          for (int i = 0; i < process.GetNumThreads(); ++i) { diff --git a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_resume.cpp b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_resume.cpp.template index 8cf786b11603..4adc9b338879 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/test_listener_resume.cpp +++ b/packages/Python/lldbsuite/test/api/multithreaded/test_listener_resume.cpp.template @@ -8,7 +8,7 @@  #include <string>  #include <thread> -#include "lldb-headers.h" +%include_SB_APIs%  #include "common.h" | 
