From owner-svn-src-all@freebsd.org Mon May 8 17:13:58 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0ED96D63758; Mon, 8 May 2017 17:13:58 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C7C40C4A; Mon, 8 May 2017 17:13:57 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v48HDuXR043147; Mon, 8 May 2017 17:13:56 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v48HDsFW043121; Mon, 8 May 2017 17:13:54 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201705081713.v48HDsFW043121@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Mon, 8 May 2017 17:13:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r317959 - in vendor/lldb/dist: include/lldb/API include/lldb/Core include/lldb/Expression include/lldb/Host include/lldb/Host/common include/lldb/Target include/lldb/Utility packages/Py... X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 May 2017 17:13:58 -0000 Author: dim Date: Mon May 8 17:13:54 2017 New Revision: 317959 URL: https://svnweb.freebsd.org/changeset/base/317959 Log: Vendor import of lldb trunk r302418: https://llvm.org/svn/llvm-project/lldb/trunk@302418 Added: vendor/lldb/dist/unittests/Host/MainLoopTest.cpp (contents, props changed) Modified: vendor/lldb/dist/include/lldb/API/SBAddress.h vendor/lldb/dist/include/lldb/API/SBInstruction.h vendor/lldb/dist/include/lldb/API/SBInstructionList.h vendor/lldb/dist/include/lldb/Core/Disassembler.h vendor/lldb/dist/include/lldb/Expression/Expression.h vendor/lldb/dist/include/lldb/Host/MainLoop.h vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h vendor/lldb/dist/include/lldb/Utility/TaskPool.h vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py vendor/lldb/dist/scripts/interface/SBInstruction.i vendor/lldb/dist/scripts/interface/SBInstructionList.i vendor/lldb/dist/source/API/SBAddress.cpp vendor/lldb/dist/source/API/SBInstruction.cpp vendor/lldb/dist/source/API/SBInstructionList.cpp vendor/lldb/dist/source/API/SBProcess.cpp vendor/lldb/dist/source/Core/Disassembler.cpp vendor/lldb/dist/source/Host/common/Editline.cpp vendor/lldb/dist/source/Host/common/MainLoop.cpp vendor/lldb/dist/source/Host/common/UDPSocket.cpp vendor/lldb/dist/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp vendor/lldb/dist/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp vendor/lldb/dist/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp vendor/lldb/dist/source/Target/ThreadPlanCallUserExpression.cpp vendor/lldb/dist/source/Utility/TaskPool.cpp vendor/lldb/dist/unittests/Host/CMakeLists.txt vendor/lldb/dist/unittests/Utility/TaskPoolTest.cpp vendor/lldb/dist/www/lldb-gdb.html Modified: vendor/lldb/dist/include/lldb/API/SBAddress.h ============================================================================== --- vendor/lldb/dist/include/lldb/API/SBAddress.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/API/SBAddress.h Mon May 8 17:13:54 2017 (r317959) @@ -103,6 +103,8 @@ protected: const lldb_private::Address *operator->() const; + friend bool operator==(const SBAddress &lhs, const SBAddress &rhs); + lldb_private::Address *get(); lldb_private::Address &ref(); @@ -117,6 +119,8 @@ private: std::unique_ptr m_opaque_ap; }; +bool operator==(const SBAddress &lhs, const SBAddress &rhs); + } // namespace lldb #endif // LLDB_SBAddress_h_ Modified: vendor/lldb/dist/include/lldb/API/SBInstruction.h ============================================================================== --- vendor/lldb/dist/include/lldb/API/SBInstruction.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/API/SBInstruction.h Mon May 8 17:13:54 2017 (r317959) @@ -53,6 +53,8 @@ public: bool HasDelaySlot(); + bool CanSetBreakpoint(); + void Print(FILE *out); bool GetDescription(lldb::SBStream &description); Modified: vendor/lldb/dist/include/lldb/API/SBInstructionList.h ============================================================================== --- vendor/lldb/dist/include/lldb/API/SBInstructionList.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/API/SBInstructionList.h Mon May 8 17:13:54 2017 (r317959) @@ -32,6 +32,15 @@ public: lldb::SBInstruction GetInstructionAtIndex(uint32_t idx); + // ---------------------------------------------------------------------- + // Returns the number of instructions between the start and end address. + // If canSetBreakpoint is true then the count will be the number of + // instructions on which a breakpoint can be set. + // ---------------------------------------------------------------------- + size_t GetInstructionsCount(const SBAddress &start, + const SBAddress &end, + bool canSetBreakpoint = false); + void Clear(); void AppendInstruction(lldb::SBInstruction inst); Modified: vendor/lldb/dist/include/lldb/Core/Disassembler.h ============================================================================== --- vendor/lldb/dist/include/lldb/Core/Disassembler.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/Core/Disassembler.h Mon May 8 17:13:54 2017 (r317959) @@ -173,6 +173,8 @@ public: virtual bool HasDelaySlot(); + bool CanSetBreakpoint (); + virtual size_t Decode(const Disassembler &disassembler, const DataExtractor &data, lldb::offset_t data_offset) = 0; Modified: vendor/lldb/dist/include/lldb/Expression/Expression.h ============================================================================== --- vendor/lldb/dist/include/lldb/Expression/Expression.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/Expression/Expression.h Mon May 8 17:13:54 2017 (r317959) @@ -99,6 +99,16 @@ public: //------------------------------------------------------------------ lldb::addr_t StartAddress() { return m_jit_start_addr; } + //------------------------------------------------------------------ + /// Called to notify the expression that it is about to be executed. + //------------------------------------------------------------------ + virtual void WillStartExecuting() {} + + //------------------------------------------------------------------ + /// Called to notify the expression that its execution has finished. + //------------------------------------------------------------------ + virtual void DidFinishExecuting() {} + virtual ExpressionTypeSystemHelper *GetTypeSystemHelper() { return nullptr; } protected: Modified: vendor/lldb/dist/include/lldb/Host/MainLoop.h ============================================================================== --- vendor/lldb/dist/include/lldb/Host/MainLoop.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/Host/MainLoop.h Mon May 8 17:13:54 2017 (r317959) @@ -42,6 +42,7 @@ private: public: typedef std::unique_ptr SignalHandleUP; + MainLoop(); ~MainLoop() override; ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp, @@ -71,6 +72,9 @@ protected: void UnregisterSignal(int signo); private: + void ProcessReadObject(IOObject::WaitableHandle handle); + void ProcessSignal(int signo); + class SignalHandle { public: ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); } @@ -97,6 +101,9 @@ private: llvm::DenseMap m_read_fds; llvm::DenseMap m_signals; +#if HAVE_SYS_EVENT_H + int m_kqueue; +#endif bool m_terminate_request : 1; }; Modified: vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h ============================================================================== --- vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h Mon May 8 17:13:54 2017 (r317959) @@ -21,15 +21,13 @@ public: Socket *&socket); private: - UDPSocket(NativeSocket socket, const UDPSocket &listen_socket); + UDPSocket(NativeSocket socket); size_t Send(const void *buf, const size_t num_bytes) override; Error Connect(llvm::StringRef name) override; Error Listen(llvm::StringRef name, int backlog) override; Error Accept(Socket *&socket) override; - Error CreateSocket(); - SocketAddress m_sockaddr; }; } Modified: vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h ============================================================================== --- vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h Mon May 8 17:13:54 2017 (r317959) @@ -117,7 +117,7 @@ protected: lldb::addr_t &start_load_addr, lldb::addr_t &function_load_addr); - void DoTakedown(bool success); + virtual void DoTakedown(bool success); void SetBreakpoints(); Modified: vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h ============================================================================== --- vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h Mon May 8 17:13:54 2017 (r317959) @@ -35,6 +35,8 @@ public: void GetDescription(Stream *s, lldb::DescriptionLevel level) override; + void DidPush() override; + void WillPop() override; lldb::StopInfoSP GetRealStopInfo() override; @@ -48,6 +50,7 @@ public: } protected: + void DoTakedown(bool success) override; private: lldb::UserExpressionSP m_user_expression_sp; // This is currently just used to ensure the Modified: vendor/lldb/dist/include/lldb/Utility/TaskPool.h ============================================================================== --- vendor/lldb/dist/include/lldb/Utility/TaskPool.h Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/include/lldb/Utility/TaskPool.h Mon May 8 17:13:54 2017 (r317959) @@ -53,50 +53,6 @@ private: static void AddTaskImpl(std::function &&task_fn); }; -// Wrapper class around the global TaskPool implementation to make it possible -// to create a set of -// tasks and then wait for the tasks to be completed by the -// WaitForNextCompletedTask call. This -// class should be used when WaitForNextCompletedTask is needed because this -// class add no other -// extra functionality to the TaskPool class and it have a very minor -// performance overhead. -template // The return type of the tasks what will be added to this - // task runner - class TaskRunner { -public: - // Add a task to the task runner what will also add the task to the global - // TaskPool. The - // function doesn't return the std::future for the task because it will be - // supplied by the - // WaitForNextCompletedTask after the task is completed. - template void AddTask(F &&f, Args &&... args); - - // Wait for the next task in this task runner to finish and then return the - // std::future what - // belongs to the finished task. If there is no task in this task runner - // (neither pending nor - // comleted) then this function will return an invalid future. Usually this - // function should be - // called in a loop processing the results of the tasks until it returns an - // invalid std::future - // what means that all task in this task runner is completed. - std::future WaitForNextCompletedTask(); - - // Convenience method to wait for all task in this TaskRunner to finish. Do - // NOT use this class - // just because of this method. Use TaskPool instead and wait for each - // std::future returned by - // AddTask in a loop. - void WaitForAllTasks(); - -private: - std::list> m_ready; - std::list> m_pending; - std::mutex m_mutex; - std::condition_variable m_cv; -}; - template std::future::type> TaskPool::AddTask(F &&f, Args &&... args) { @@ -126,64 +82,10 @@ template <> struct TaskPool::RunTaskImpl static void Run() {} }; -template -template -void TaskRunner::AddTask(F &&f, Args &&... args) { - std::unique_lock lock(m_mutex); - auto it = m_pending.emplace(m_pending.end()); - *it = std::move(TaskPool::AddTask( - [this, it](F f, Args... args) { - T &&r = f(std::forward(args)...); - - std::unique_lock lock(this->m_mutex); - this->m_ready.splice(this->m_ready.end(), this->m_pending, it); - lock.unlock(); - - this->m_cv.notify_one(); - return r; - }, - std::forward(f), std::forward(args)...)); -} - -template <> -template -void TaskRunner::AddTask(F &&f, Args &&... args) { - std::unique_lock lock(m_mutex); - auto it = m_pending.emplace(m_pending.end()); - *it = std::move(TaskPool::AddTask( - [this, it](F f, Args... args) { - f(std::forward(args)...); - - std::unique_lock lock(this->m_mutex); - this->m_ready.emplace_back(std::move(*it)); - this->m_pending.erase(it); - lock.unlock(); - - this->m_cv.notify_one(); - }, - std::forward(f), std::forward(args)...)); -} - -template std::future TaskRunner::WaitForNextCompletedTask() { - std::unique_lock lock(m_mutex); - if (m_ready.empty() && m_pending.empty()) - return std::future(); // No more tasks - - if (m_ready.empty()) - m_cv.wait(lock, [this]() { return !this->m_ready.empty(); }); - - std::future res = std::move(m_ready.front()); - m_ready.pop_front(); - - lock.unlock(); - res.wait(); - - return std::move(res); -} - -template void TaskRunner::WaitForAllTasks() { - while (WaitForNextCompletedTask().valid()) - ; -} +// Run 'func' on every value from begin .. end-1. Each worker will grab +// 'batch_size' numbers at a time to work on, so for very fast functions, batch +// should be large enough to avoid too much cache line contention. +void TaskMapOverInt(size_t begin, size_t end, + std::function const &func); #endif // #ifndef utility_TaskPool_h_ Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py ============================================================================== --- vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py Mon May 8 17:13:54 2017 (r317959) @@ -12,6 +12,7 @@ from lldbsuite.test import lldbutil class MultilineExpressionsTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True def setUp(self): # Call super's setUp(). @@ -60,3 +61,30 @@ class MultilineExpressionsTestCase(TestB child.expect_exact(prompt) self.expect(child.before, exe=False, patterns=['= 5']) + + @skipIfRemote + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr22274: need a pexpect replacement for windows") + def test_empty_list(self): + """Test printing an empty list of expressions""" + import pexpect + prompt = "(lldb) " + + # So that the child gets torn down after the test + self.child = pexpect.spawn( + "%s %s" % + (lldbtest_config.lldbExec, self.lldbOption)) + child = self.child + + # Turn on logging for what the child sends back. + if self.TraceOn(): + child.logfile_read = sys.stdout + + # We expect a prompt, then send "print" to start a list of expressions, + # then an empty line. We expect a prompt back. + child.expect_exact(prompt) + child.sendline("print") + child.expect_exact('1:') + child.sendline("") + child.expect_exact(prompt) Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py ============================================================================== --- vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py Mon May 8 17:13:54 2017 (r317959) @@ -62,12 +62,11 @@ class StepOverBreakpointsTestCase(TestBa instructions = function.GetInstructions(self.target) addr_1 = self.breakpoint1.GetLocationAtIndex(0).GetAddress() addr_4 = self.breakpoint4.GetLocationAtIndex(0).GetAddress() - for i in range(instructions.GetSize()) : - addr = instructions.GetInstructionAtIndex(i).GetAddress() - if (addr == addr_1) : index_1 = i - if (addr == addr_4) : index_4 = i - steps_expected = index_4 - index_1 + # if third argument is true then the count will be the number of + # instructions on which a breakpoint can be set. + # start = addr_1, end = addr_4, canSetBreakpoint = True + steps_expected = instructions.GetInstructionsCount(addr_1, addr_4, True) step_count = 0 # Step from breakpoint_1 to breakpoint_4 while True: Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py ============================================================================== --- vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py Mon May 8 17:13:54 2017 (r317959) @@ -171,17 +171,45 @@ class ReturnValueTestCase(TestBase): #self.return_and_test_struct_value ("return_one_int_one_double_packed") self.return_and_test_struct_value("return_one_int_one_long") - # icc and gcc don't support this extension. - if self.getCompiler().endswith('clang'): - self.return_and_test_struct_value("return_vector_size_float32_8") - self.return_and_test_struct_value("return_vector_size_float32_16") - self.return_and_test_struct_value("return_vector_size_float32_32") - self.return_and_test_struct_value( - "return_ext_vector_size_float32_2") - self.return_and_test_struct_value( - "return_ext_vector_size_float32_4") - self.return_and_test_struct_value( - "return_ext_vector_size_float32_8") + @expectedFailureAll(oslist=["freebsd"], archs=["i386"]) + @expectedFailureAll(oslist=["macosx"], archs=["i386"], bugnumber="") + @expectedFailureAll( + oslist=["linux"], + compiler="clang", + compiler_version=[ + "<=", + "3.6"], + archs=["i386"]) + @expectedFailureAll( + bugnumber="llvm.org/pr25785", + hostoslist=["windows"], + compiler="gcc", + archs=["i386"], + triple='.*-android') + @expectedFailureAll(compiler=["gcc"], archs=["x86_64", "i386"]) + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778") + def test_vector_values(self): + self.build() + exe = os.path.join(os.getcwd(), "a.out") + error = lldb.SBError() + + self.target = self.dbg.CreateTarget(exe) + self.assertTrue(self.target, VALID_TARGET) + + main_bktp = self.target.BreakpointCreateByName("main", exe) + self.assertTrue(main_bktp, VALID_BREAKPOINT) + + self.process = self.target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint( + self.process, main_bktp)), 1) + + self.return_and_test_struct_value("return_vector_size_float32_8") + self.return_and_test_struct_value("return_vector_size_float32_16") + self.return_and_test_struct_value("return_vector_size_float32_32") + self.return_and_test_struct_value("return_ext_vector_size_float32_2") + self.return_and_test_struct_value("return_ext_vector_size_float32_4") + self.return_and_test_struct_value("return_ext_vector_size_float32_8") def return_and_test_struct_value(self, func_name): """Pass in the name of the function to return from - takes in value, returns value.""" Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py ============================================================================== --- vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py Mon May 8 17:13:54 2017 (r317959) @@ -14,6 +14,7 @@ class TestGdbRemoteHostInfo(GdbRemoteTes mydir = TestBase.compute_mydir(__file__) KNOWN_HOST_INFO_KEYS = set([ + "arch", "cputype", "cpusubtype", "distribution_id", Modified: vendor/lldb/dist/scripts/interface/SBInstruction.i ============================================================================== --- vendor/lldb/dist/scripts/interface/SBInstruction.i Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/scripts/interface/SBInstruction.i Mon May 8 17:13:54 2017 (r317959) @@ -54,6 +54,9 @@ public: bool HasDelaySlot (); + bool + CanSetBreakpoint (); + void Print (FILE *out); Modified: vendor/lldb/dist/scripts/interface/SBInstructionList.i ============================================================================== --- vendor/lldb/dist/scripts/interface/SBInstructionList.i Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/scripts/interface/SBInstructionList.i Mon May 8 17:13:54 2017 (r317959) @@ -44,6 +44,9 @@ public: lldb::SBInstruction GetInstructionAtIndex (uint32_t idx); + size_t GetInstructionsCount(const SBAddress &start, const SBAddress &end, + bool canSetBreakpoint); + void Clear (); Modified: vendor/lldb/dist/source/API/SBAddress.cpp ============================================================================== --- vendor/lldb/dist/source/API/SBAddress.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/API/SBAddress.cpp Mon May 8 17:13:54 2017 (r317959) @@ -55,6 +55,12 @@ const SBAddress &SBAddress::operator=(co return *this; } +bool lldb::operator==(const SBAddress &lhs, const SBAddress &rhs) { + if (lhs.IsValid() && rhs.IsValid()) + return lhs.ref() == rhs.ref(); + return false; +} + bool SBAddress::IsValid() const { return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); } Modified: vendor/lldb/dist/source/API/SBInstruction.cpp ============================================================================== --- vendor/lldb/dist/source/API/SBInstruction.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/API/SBInstruction.cpp Mon May 8 17:13:54 2017 (r317959) @@ -176,6 +176,13 @@ bool SBInstruction::HasDelaySlot() { return false; } +bool SBInstruction::CanSetBreakpoint () { + lldb::InstructionSP inst_sp(GetOpaque()); + if (inst_sp) + return inst_sp->CanSetBreakpoint(); + return false; +} + lldb::InstructionSP SBInstruction::GetOpaque() { if (m_opaque_sp) return m_opaque_sp->GetSP(); Modified: vendor/lldb/dist/source/API/SBInstructionList.cpp ============================================================================== --- vendor/lldb/dist/source/API/SBInstructionList.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/API/SBInstructionList.cpp Mon May 8 17:13:54 2017 (r317959) @@ -9,6 +9,7 @@ #include "lldb/API/SBInstructionList.h" #include "lldb/API/SBInstruction.h" +#include "lldb/API/SBAddress.h" #include "lldb/API/SBStream.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" @@ -49,6 +50,31 @@ SBInstruction SBInstructionList::GetInst return inst; } +size_t SBInstructionList::GetInstructionsCount(const SBAddress &start, + const SBAddress &end, + bool canSetBreakpoint) { + size_t num_instructions = GetSize(); + size_t i = 0; + SBAddress addr; + size_t lower_index = 0; + size_t upper_index = 0; + size_t instructions_to_skip = 0; + for (i = 0; i < num_instructions; ++i) { + addr = GetInstructionAtIndex(i).GetAddress(); + if (start == addr) + lower_index = i; + if (end == addr) + upper_index = i; + } + if (canSetBreakpoint) + for (i = lower_index; i <= upper_index; ++i) { + SBInstruction insn = GetInstructionAtIndex(i); + if (!insn.CanSetBreakpoint()) + ++instructions_to_skip; + } + return upper_index - lower_index - instructions_to_skip; +} + void SBInstructionList::Clear() { m_opaque_sp.reset(); } void SBInstructionList::AppendInstruction(SBInstruction insn) {} Modified: vendor/lldb/dist/source/API/SBProcess.cpp ============================================================================== --- vendor/lldb/dist/source/API/SBProcess.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/API/SBProcess.cpp Mon May 8 17:13:54 2017 (r317959) @@ -1157,22 +1157,34 @@ uint32_t SBProcess::LoadImage(lldb::SBFi uint32_t SBProcess::LoadImage(const lldb::SBFileSpec &sb_local_image_spec, const lldb::SBFileSpec &sb_remote_image_spec, lldb::SBError &sb_error) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); ProcessSP process_sp(GetSP()); if (process_sp) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process_sp->GetRunLock())) { + if (log) + log->Printf("SBProcess(%p)::LoadImage() => calling Platform::LoadImage" + "for: %s", + static_cast(process_sp.get()), + sb_local_image_spec.GetFilename()); + std::lock_guard guard( - process_sp->GetTarget().GetAPIMutex()); + process_sp->GetTarget().GetAPIMutex()); PlatformSP platform_sp = process_sp->GetTarget().GetPlatform(); return platform_sp->LoadImage(process_sp.get(), *sb_local_image_spec, *sb_remote_image_spec, sb_error.ref()); } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); if (log) log->Printf("SBProcess(%p)::LoadImage() => error: process is running", static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } + } else { + if (log) + log->Printf("SBProcess(%p)::LoadImage() => error: called with invalid" + " process", + static_cast(process_sp.get())); + sb_error.SetErrorString("process is invalid"); } return LLDB_INVALID_IMAGE_TOKEN; } Modified: vendor/lldb/dist/source/Core/Disassembler.cpp ============================================================================== --- vendor/lldb/dist/source/Core/Disassembler.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/Core/Disassembler.cpp Mon May 8 17:13:54 2017 (r317959) @@ -759,6 +759,10 @@ bool Instruction::DumpEmulation(const Ar return false; } +bool Instruction::CanSetBreakpoint () { + return !HasDelaySlot(); +} + bool Instruction::HasDelaySlot() { // Default is false. return false; Modified: vendor/lldb/dist/source/Host/common/Editline.cpp ============================================================================== --- vendor/lldb/dist/source/Host/common/Editline.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/Host/common/Editline.cpp Mon May 8 17:13:54 2017 (r317959) @@ -367,7 +367,7 @@ void Editline::MoveCursor(CursorLocation if (to == CursorLocation::EditingCursor) { toColumn = editline_cursor_position - (editline_cursor_row * m_terminal_width) + 1; - } else if (to == CursorLocation::BlockEnd) { + } else if (to == CursorLocation::BlockEnd && !m_input_lines.empty()) { toColumn = ((m_input_lines[m_input_lines.size() - 1].length() + GetPromptWidth()) % 80) + Modified: vendor/lldb/dist/source/Host/common/MainLoop.cpp ============================================================================== --- vendor/lldb/dist/source/Host/common/MainLoop.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/Host/common/MainLoop.cpp Mon May 8 17:13:54 2017 (r317959) @@ -18,6 +18,11 @@ #include #include +// Multiplexing is implemented using kqueue on systems that support it (BSD +// variants including OSX). On linux we use ppoll, while android uses pselect +// (ppoll is present but not implemented properly). On windows we use WSApoll +// (which does not support signals). + #if HAVE_SYS_EVENT_H #include #elif defined(LLVM_ON_WIN32) @@ -65,92 +70,72 @@ static void SignalHandler(int signo, sig class MainLoop::RunImpl { public: - // TODO: Use llvm::Expected - static std::unique_ptr Create(MainLoop &loop, Error &error); - ~RunImpl(); + RunImpl(MainLoop &loop); + ~RunImpl() = default; Error Poll(); - - template void ForEachReadFD(F &&f); - template void ForEachSignal(F &&f); + void ProcessEvents(); private: MainLoop &loop; #if HAVE_SYS_EVENT_H - int queue_id; std::vector in_events; struct kevent out_events[4]; int num_events = -1; - RunImpl(MainLoop &loop, int queue_id) : loop(loop), queue_id(queue_id) { - in_events.reserve(loop.m_read_fds.size() + loop.m_signals.size()); - } #else - std::vector signals; #ifdef FORCE_PSELECT fd_set read_fd_set; #else std::vector read_fds; #endif - RunImpl(MainLoop &loop) : loop(loop) { - signals.reserve(loop.m_signals.size()); - } - sigset_t get_sigmask(); #endif }; #if HAVE_SYS_EVENT_H -MainLoop::RunImpl::~RunImpl() { - int r = close(queue_id); - assert(r == 0); - (void)r; -} -std::unique_ptr MainLoop::RunImpl::Create(MainLoop &loop, Error &error) -{ - error.Clear(); - int queue_id = kqueue(); - if(queue_id < 0) { - error = Error(errno, eErrorTypePOSIX); - return nullptr; - } - return std::unique_ptr(new RunImpl(loop, queue_id)); +MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { + in_events.reserve(loop.m_read_fds.size()); } Error MainLoop::RunImpl::Poll() { - in_events.resize(loop.m_read_fds.size() + loop.m_signals.size()); + in_events.resize(loop.m_read_fds.size()); unsigned i = 0; for (auto &fd : loop.m_read_fds) EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0); - for (const auto &sig : loop.m_signals) - EV_SET(&in_events[i++], sig.first, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); - - num_events = kevent(queue_id, in_events.data(), in_events.size(), out_events, - llvm::array_lengthof(out_events), nullptr); + num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(), + out_events, llvm::array_lengthof(out_events), nullptr); if (num_events < 0) return Error("kevent() failed with error %d\n", num_events); return Error(); } -template void MainLoop::RunImpl::ForEachReadFD(F &&f) { +void MainLoop::RunImpl::ProcessEvents() { assert(num_events >= 0); for (int i = 0; i < num_events; ++i) { - f(out_events[i].ident); if (loop.m_terminate_request) return; + switch (out_events[i].filter) { + case EVFILT_READ: + loop.ProcessReadObject(out_events[i].ident); + break; + case EVFILT_SIGNAL: + loop.ProcessSignal(out_events[i].ident); + break; + default: + llvm_unreachable("Unknown event"); + } } } -template void MainLoop::RunImpl::ForEachSignal(F && f) {} #else -MainLoop::RunImpl::~RunImpl() {} -std::unique_ptr MainLoop::RunImpl::Create(MainLoop &loop, Error &error) -{ - error.Clear(); - return std::unique_ptr(new RunImpl(loop)); +MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { +#ifndef FORCE_PSELECT + read_fds.reserve(loop.m_read_fds.size()); +#endif } sigset_t MainLoop::RunImpl::get_sigmask() { @@ -162,18 +147,14 @@ sigset_t MainLoop::RunImpl::get_sigmask( assert(ret == 0); (void) ret; - for (const auto &sig : loop.m_signals) { - signals.push_back(sig.first); + for (const auto &sig : loop.m_signals) sigdelset(&sigmask, sig.first); - } return sigmask; #endif } #ifdef FORCE_PSELECT Error MainLoop::RunImpl::Poll() { - signals.clear(); - FD_ZERO(&read_fd_set); int nfds = 0; for (const auto &fd : loop.m_read_fds) { @@ -188,20 +169,8 @@ Error MainLoop::RunImpl::Poll() { return Error(); } - -template void MainLoop::RunImpl::ForEachReadFD(F &&f) { - for (const auto &fd : loop.m_read_fds) { - if(!FD_ISSET(fd.first, &read_fd_set)) - continue; - - f(fd.first); - if (loop.m_terminate_request) - return; - } -} #else Error MainLoop::RunImpl::Poll() { - signals.clear(); read_fds.clear(); sigset_t sigmask = get_sigmask(); @@ -220,33 +189,47 @@ Error MainLoop::RunImpl::Poll() { return Error(); } +#endif -template void MainLoop::RunImpl::ForEachReadFD(F &&f) { +void MainLoop::RunImpl::ProcessEvents() { +#ifdef FORCE_PSELECT + for (const auto &fd : loop.m_read_fds) { + if (!FD_ISSET(fd.first, &read_fd_set)) + continue; + IOObject::WaitableHandle handle = fd.first; +#else for (const auto &fd : read_fds) { if ((fd.revents & POLLIN) == 0) continue; - - f(fd.fd); + IOObject::WaitableHandle handle = fd.fd; +#endif if (loop.m_terminate_request) return; - } -} -#endif -template void MainLoop::RunImpl::ForEachSignal(F &&f) { - for (int sig : signals) { - if (g_signal_flags[sig] == 0) - continue; // No signal - g_signal_flags[sig] = 0; - f(sig); + loop.ProcessReadObject(handle); + } + for (const auto &entry : loop.m_signals) { if (loop.m_terminate_request) return; + if (g_signal_flags[entry.first] == 0) + continue; // No signal + g_signal_flags[entry.first] = 0; + loop.ProcessSignal(entry.first); } } #endif +MainLoop::MainLoop() { +#if HAVE_SYS_EVENT_H + m_kqueue = kqueue(); + assert(m_kqueue >= 0); +#endif +} MainLoop::~MainLoop() { +#if HAVE_SYS_EVENT_H + close(m_kqueue); +#endif assert(m_read_fds.size() == 0); assert(m_signals.size() == 0); } @@ -298,24 +281,30 @@ MainLoop::RegisterSignal(int signo, cons new_action.sa_flags = SA_SIGINFO; sigemptyset(&new_action.sa_mask); sigaddset(&new_action.sa_mask, signo); - sigset_t old_set; - if (int ret = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, &old_set)) { - error.SetErrorStringWithFormat("pthread_sigmask failed with error %d\n", - ret); - return nullptr; - } - info.was_blocked = sigismember(&old_set, signo); - if (sigaction(signo, &new_action, &info.old_action) == -1) { - error.SetErrorToErrno(); - if (!info.was_blocked) - pthread_sigmask(SIG_UNBLOCK, &new_action.sa_mask, nullptr); - return nullptr; - } + g_signal_flags[signo] = 0; + + // Even if using kqueue, the signal handler will still be invoked, so it's + // important to replace it with our "bening" handler. + int ret = sigaction(signo, &new_action, &info.old_action); + assert(ret == 0 && "sigaction failed"); + +#if HAVE_SYS_EVENT_H + struct kevent ev; + EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); + ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr); + assert(ret == 0); +#endif + // If we're using kqueue, the signal needs to be unblocked in order to recieve + // it. If using pselect/ppoll, we need to block it, and later unblock it as a + // part of the system call. + ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK, + &new_action.sa_mask, &old_set); + assert(ret == 0 && "pthread_sigmask failed"); + info.was_blocked = sigismember(&old_set, signo); m_signals.insert({signo, info}); - g_signal_flags[signo] = 0; return SignalHandleUP(new SignalHandle(*this, signo)); #endif @@ -331,7 +320,6 @@ void MainLoop::UnregisterSignal(int sign #if SIGNAL_POLLING_UNSUPPORTED Error("Signal polling is not supported on this platform."); #else - // We undo the actions of RegisterSignal on a best-effort basis. auto it = m_signals.find(signo); assert(it != m_signals.end()); @@ -340,8 +328,17 @@ void MainLoop::UnregisterSignal(int sign sigset_t set; sigemptyset(&set); sigaddset(&set, signo); - pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, &set, - nullptr); + int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, + &set, nullptr); + assert(ret == 0); + (void)ret; + +#if HAVE_SYS_EVENT_H + struct kevent ev; + EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0); + ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr); + assert(ret == 0); +#endif m_signals.erase(it); #endif @@ -351,32 +348,31 @@ Error MainLoop::Run() { m_terminate_request = false; Error error; - auto impl = RunImpl::Create(*this, error); - if (!impl) - return error; + RunImpl impl(*this); // run until termination or until we run out of things to listen to while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) { - error = impl->Poll(); + error = impl.Poll(); if (error.Fail()) return error; - impl->ForEachSignal([&](int sig) { - auto it = m_signals.find(sig); - if (it != m_signals.end()) - it->second.callback(*this); // Do the work - }); - if (m_terminate_request) - return Error(); + impl.ProcessEvents(); - impl->ForEachReadFD([&](int fd) { - auto it = m_read_fds.find(fd); - if (it != m_read_fds.end()) - it->second(*this); // Do the work - }); if (m_terminate_request) return Error(); } return Error(); } + +void MainLoop::ProcessSignal(int signo) { + auto it = m_signals.find(signo); + if (it != m_signals.end()) + it->second.callback(*this); // Do the work +} + +void MainLoop::ProcessReadObject(IOObject::WaitableHandle handle) { + auto it = m_read_fds.find(handle); + if (it != m_read_fds.end()) + it->second(*this); // Do the work +} Modified: vendor/lldb/dist/source/Host/common/UDPSocket.cpp ============================================================================== --- vendor/lldb/dist/source/Host/common/UDPSocket.cpp Mon May 8 17:13:50 2017 (r317958) +++ vendor/lldb/dist/source/Host/common/UDPSocket.cpp Mon May 8 17:13:54 2017 (r317959) @@ -28,31 +28,41 @@ const int kDomain = AF_INET; const int kType = SOCK_DGRAM; static const char *g_not_supported_error = "Not supported"; -} // namespace - -UDPSocket::UDPSocket(bool should_close, bool child_processes_inherit) - : Socket(ProtocolUdp, should_close, child_processes_inherit) {} +} -UDPSocket::UDPSocket(NativeSocket socket, const UDPSocket &listen_socket) - : Socket(ProtocolUdp, listen_socket.m_should_close_fd, - listen_socket.m_child_processes_inherit) { +UDPSocket::UDPSocket(NativeSocket socket) : Socket(ProtocolUdp, true, true) { m_socket = socket; } +UDPSocket::UDPSocket(bool should_close, bool child_processes_inherit) + : Socket(ProtocolUdp, should_close, child_processes_inherit) {} + size_t UDPSocket::Send(const void *buf, const size_t num_bytes) { return ::sendto(m_socket, static_cast(buf), num_bytes, 0, m_sockaddr, m_sockaddr.GetLength()); } Error UDPSocket::Connect(llvm::StringRef name) { + return Error("%s", g_not_supported_error); +} + +Error UDPSocket::Listen(llvm::StringRef name, int backlog) { + return Error("%s", g_not_supported_error); +} + +Error UDPSocket::Accept(Socket *&socket) { + return Error("%s", g_not_supported_error); +} + +Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, + Socket *&socket) { + std::unique_ptr final_socket; + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); if (log) log->Printf("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); Error error; - if (error.Fail()) - return error; - std::string host_str; std::string port_str; int32_t port = INT32_MIN; @@ -84,11 +94,12 @@ Error UDPSocket::Connect(llvm::StringRef for (struct addrinfo *service_info_ptr = service_info_list; service_info_ptr != nullptr; service_info_ptr = service_info_ptr->ai_next) { - m_socket = Socket::CreateSocket( + auto send_fd = CreateSocket( service_info_ptr->ai_family, service_info_ptr->ai_socktype, - service_info_ptr->ai_protocol, m_child_processes_inherit, error); + service_info_ptr->ai_protocol, child_processes_inherit, error); if (error.Success()) { - m_sockaddr = service_info_ptr; + final_socket.reset(new UDPSocket(send_fd)); + final_socket->m_sockaddr = service_info_ptr; break; } else continue; @@ -96,17 +107,16 @@ Error UDPSocket::Connect(llvm::StringRef ::freeaddrinfo(service_info_list); - if (IsValid()) + if (!final_socket) return error; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***