[Lldb-commits] [lldb] r251917 - Changes for Bug 25251
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Tue Nov 3 07:22:55 PST 2015
Hi,
in the future, please add "lldb-commits" as a subscriber when you are
having your patches reviewed.
pl
On 3 November 2015 at 06:24, Ravitheja Addepally via lldb-commits
<lldb-commits at lists.llvm.org> wrote:
> Author: ravitheja
> Date: Tue Nov 3 08:24:24 2015
> New Revision: 251917
>
> URL: http://llvm.org/viewvc/llvm-project?rev=251917&view=rev
> Log:
> Changes for Bug 25251
>
> Summary:
> The solution to bug 24074,rL249673 needed
> to parse the function information from the Dwarf in order
> to set the SymbolContext. For that, GetFunction was called
> for the parent in GetTypeForDIE, which parses the
> ChildParameters and in the flow, GetTypeForDIE was called
> for one of the sibling die and so an infinite
> loop was triggered by calling GetFunction repeatedly for the
> same function.
>
> The changes in this revision modify the GetTypeForDIE to only
> resolve the function context in the Type Lookup flow and so
> prevent the infinite loop.
>
> A testcase has also been added to check for regression in the
> future and a test vector had been added to the testcase of
> 24074.
>
> Reviewers: jingham, tberghammer, clayborg
>
> Differential Revision: http://reviews.llvm.org/D14202
>
> Added:
> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/
> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile
> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp (with props)
> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
> Modified:
> lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
> lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/main.c
> lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
> lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
>
> Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile?rev=251917&view=auto
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile (added)
> +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile Tue Nov 3 08:24:24 2015
> @@ -0,0 +1,6 @@
> +LEVEL = ../../../make
> +
> +CXXFLAGS += -std=c++11
> +CXX_SOURCES := ParallelTask.cpp
> +ENABLE_STD_THREADS := YES
> +include $(LEVEL)/Makefile.rules
>
> Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp?rev=251917&view=auto
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp (added)
> +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp Tue Nov 3 08:24:24 2015
> @@ -0,0 +1,151 @@
> +#include <cstdint>
> +#include <thread>
> +#include <vector>
> +#include <queue>
> +#include <future>
> +#include <iostream>
> +#include <cassert>
> +
> +class TaskPoolImpl
> +{
> +public:
> + TaskPoolImpl(uint32_t num_threads) :
> + m_stop(false)
> + {
> + for (uint32_t i = 0; i < num_threads; ++i)
> + m_threads.emplace_back(Worker, this);
> + }
> +
> + ~TaskPoolImpl()
> + {
> + Stop();
> + }
> +
> + template<typename F, typename... Args>
> + std::future<typename std::result_of<F(Args...)>::type>
> + AddTask(F&& f, Args&&... args)
> + {
> + auto task = std::make_shared<std::packaged_task<typename std::result_of<F(Args...)>::type()>>(
> + std::bind(std::forward<F>(f), std::forward<Args>(args)...));
> +
> + std::unique_lock<std::mutex> lock(m_tasks_mutex);
> + assert(!m_stop && "Can't add task to TaskPool after it is stopped");
> + m_tasks.emplace([task](){ (*task)(); });
> + lock.unlock();
> + m_tasks_cv.notify_one();
> +
> + return task->get_future();
> + }
> +
> + void
> + Stop()
> + {
> + std::unique_lock<std::mutex> lock(m_tasks_mutex);
> + m_stop = true;
> + m_tasks_mutex.unlock();
> + m_tasks_cv.notify_all();
> + for (auto& t : m_threads)
> + t.join();
> + }
> +
> +private:
> + static void
> + Worker(TaskPoolImpl* pool)
> + {
> + while (true)
> + {
> + std::unique_lock<std::mutex> lock(pool->m_tasks_mutex);
> + if (pool->m_tasks.empty())
> + pool->m_tasks_cv.wait(lock, [pool](){ return !pool->m_tasks.empty() || pool->m_stop; });
> + if (pool->m_tasks.empty())
> + break;
> +
> + std::function<void()> f = pool->m_tasks.front();
> + pool->m_tasks.pop();
> + lock.unlock();
> +
> + f();
> + }
> + }
> +
> + std::queue<std::function<void()>> m_tasks;
> + std::mutex m_tasks_mutex;
> + std::condition_variable m_tasks_cv;
> + bool m_stop;
> + std::vector<std::thread> m_threads;
> +};
> +
> +class TaskPool
> +{
> +public:
> + // Add a new task to the thread pool and return a std::future belongs for the newly created task.
> + // The caller of this function have to wait on the future for this task to complete.
> + template<typename F, typename... Args>
> + static std::future<typename std::result_of<F(Args...)>::type>
> + AddTask(F&& f, Args&&... args)
> + {
> + return GetImplementation().AddTask(std::forward<F>(f), std::forward<Args>(args)...);
> + }
> +
> + // Run all of the specified tasks on the thread pool and wait until all of them are finished
> + // before returning
> + template<typename... T>
> + static void
> + RunTasks(T&&... t)
> + {
> + RunTaskImpl<T...>::Run(std::forward<T>(t)...);
> + }
> +
> +private:
> + static TaskPoolImpl&
> + GetImplementation()
> + {
> + static TaskPoolImpl g_task_pool_impl(std::thread::hardware_concurrency());
> + return g_task_pool_impl;
> + }
> +
> + template<typename... T>
> + struct RunTaskImpl;
> +};
> +
> +template<typename H, typename... T>
> +struct TaskPool::RunTaskImpl<H, T...>
> +{
> + static void
> + Run(H&& h, T&&... t)
> + {
> + auto f = AddTask(std::forward<H>(h));
> + RunTaskImpl<T...>::Run(std::forward<T>(t)...);
> + f.wait();
> + }
> +};
> +
> +template<>
> +struct TaskPool::RunTaskImpl<>
> +{
> + static void
> + Run() {}
> +};
> +
> +int main()
> +{
> + std::vector<std::future<uint32_t>> tasks;
> + for (int i = 0; i < 100000; ++i)
> + {
> + tasks.emplace_back(TaskPool::AddTask([](int i){
> + uint32_t s = 0;
> + for (int j = 0; j <= i; ++j)
> + s += j;
> + return s;
> + },
> + i));
> + }
> +
> + for (auto& it : tasks) // Set breakpoint here
> + it.wait();
> +
> + TaskPool::RunTasks(
> + []() { return 1; },
> + []() { return "aaaa"; }
> + );
> +}
>
> Propchange: lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp
> ------------------------------------------------------------------------------
> svn:executable = *
>
> Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py?rev=251917&view=auto
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py (added)
> +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py Tue Nov 3 08:24:24 2015
> @@ -0,0 +1,54 @@
> +"""
> +Test regression for Bug 25251.
> +"""
> +
> +import os, time
> +import unittest2
> +import lldb
> +from lldbsuite.test.lldbtest import *
> +import lldbsuite.test.lldbutil as lldbutil
> +
> +class BreakpointAfterJoinTestCase(TestBase):
> +
> + mydir = TestBase.compute_mydir(__file__)
> +
> + def setUp(self):
> + # Call super's setUp().
> + TestBase.setUp(self)
> + # Find the line number for our breakpoint.
> + self.breakpoint = line_number('ParallelTask.cpp', '// Set breakpoint here')
> +
> + def test(self):
> + """Test breakpoint handling after a thread join."""
> + self.build(dictionary=self.getBuildFlags())
> +
> + exe = os.path.join(os.getcwd(), "a.out")
> + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
> +
> + # This should create a breakpoint
> + lldbutil.run_break_set_by_file_and_line (self, "ParallelTask.cpp", self.breakpoint, num_expected_locations=-1)
> +
> + # The breakpoint list should show 1 location.
> + self.expect("breakpoint list -f", "Breakpoint location shown correctly",
> + substrs = ["1: file = 'ParallelTask.cpp', line = %d, exact_match = 0" % self.breakpoint])
> +
> + # Run the program.
> + 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'])
> +
> + # This should not result in a segmentation fault
> + self.expect("thread backtrace all", STOPPED_DUE_TO_BREAKPOINT,
> + substrs = ["stop reason = breakpoint 1."])
> +
> + # Run to completion
> + self.runCmd("continue")
> +
> +if __name__ == '__main__':
> + import atexit
> + lldb.SBDebugger.Initialize()
> + atexit.register(lambda: lldb.SBDebugger.Terminate())
> + unittest2.main()
>
> Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py?rev=251917&r1=251916&r2=251917&view=diff
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py (original)
> +++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py Tue Nov 3 08:24:24 2015
> @@ -32,7 +32,7 @@ class TypedefTestCase(TestBase):
> """Test 'image lookup -t a' at different scopes and check for correct display."""
> exe = os.path.join(os.getcwd(), "a.out")
> self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
> - typearray = ("float", "float", "char", "float", "int", "double", "float", "float")
> + typearray = ("float", "float", "char", "double *", "float", "int", "double", "float", "float")
> arraylen = len(typearray)+1
> for i in range(1,arraylen):
> loc_line = line_number('main.c', '// Set break point ' + str(i) + '.')
>
> Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/main.c
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/main.c?rev=251917&r1=251916&r2=251917&view=diff
> ==============================================================================
> --- lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/main.c (original)
> +++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/typedef/main.c Tue Nov 3 08:24:24 2015
> @@ -6,6 +6,11 @@
> // License. See LICENSE.TXT for details.
> //
> //===----------------------------------------------------------------------===//
> +void test()
> +{
> + typedef double * a;
> + a b = 0; // Set break point 4.
> +}
> int main (int argc, char const *argv[])
> {
> typedef float a;
> @@ -16,25 +21,26 @@ int main (int argc, char const *argv[])
> typedef char a;
> i++;
> a charvariable = 'a'; // Set break point 3.
> + test();
> }
> {
> int c = 0;
> - c++; // Set break point 4.
> + c++; // Set break point 5.
> for(i = 0 ; i < 1 ; i++)
> {
> typedef int a;
> a b;
> - b = 7; // Set break point 5.
> + b = 7; // Set break point 6.
> }
> for(i = 0 ; i < 1 ; i++)
> {
> typedef double a;
> a b;
> - b = 3.14; // Set break point 6.
> + b = 3.14; // Set break point 7.
> }
> - c = 1; // Set break point 7.
> + c = 1; // Set break point 8.
> }
> floatvariable = 2.5;
> - floatvariable = 2.8; // Set break point 8.
> + floatvariable = 2.8; // Set break point 9.
> return 0;
> }
>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=251917&r1=251916&r2=251917&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Nov 3 08:24:24 2015
> @@ -1559,14 +1559,14 @@ SymbolFileDWARF::CompleteType (CompilerT
> }
>
> Type*
> -SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed)
> +SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context)
> {
> if (die)
> {
> Type *type = GetDIEToType().lookup (die.GetDIE());
>
> if (type == NULL)
> - type = GetTypeForDIE (die).get();
> + type = GetTypeForDIE (die, resolve_function_context).get();
>
> if (assert_not_being_parsed)
> {
> @@ -2927,7 +2927,7 @@ SymbolFileDWARF::FindTypes (const Symbol
> if (!DIEInDeclContext(parent_decl_ctx, die))
> continue; // The containing decl contexts don't match
>
> - Type *matching_type = ResolveType (die);
> + Type *matching_type = ResolveType (die, true, true);
> if (matching_type)
> {
> // We found a type pointer, now find the shared pointer form our type list
> @@ -3065,7 +3065,7 @@ SymbolFileDWARF::FindNamespace (const Sy
> }
>
> TypeSP
> -SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die)
> +SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context)
> {
> TypeSP type_sp;
> if (die)
> @@ -3084,7 +3084,7 @@ SymbolFileDWARF::GetTypeForDIE (const DW
> parent_die = parent_die->GetParent();
> }
> SymbolContext sc_backup = sc;
> - if (parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc))
> + if (resolve_function_context && parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc))
> sc = sc_backup;
>
> type_sp = ParseType(sc, die, NULL);
> @@ -3270,7 +3270,7 @@ SymbolFileDWARF::FindCompleteObjCDefinit
>
> if (try_resolving_type)
> {
> - Type *resolved_type = ResolveType (type_die, false);
> + Type *resolved_type = ResolveType (type_die, false, true);
> if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
> {
> DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=251917&r1=251916&r2=251917&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Tue Nov 3 08:24:24 2015
> @@ -148,7 +148,8 @@ public:
>
> lldb_private::Type *
> ResolveType (const DWARFDIE &die,
> - bool assert_not_being_parsed = true);
> + bool assert_not_being_parsed = true,
> + bool resolve_function_context = false);
>
> lldb_private::CompilerDecl
> GetDeclForUID (lldb::user_id_t uid) override;
> @@ -434,7 +435,7 @@ protected:
> lldb_private::SymbolContextList& sc_list);
>
> lldb::TypeSP
> - GetTypeForDIE (const DWARFDIE &die);
> + GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context = false);
>
> void
> Index();
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
More information about the lldb-commits
mailing list