[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