C++ 通过c+;的lldb未解析断点+;应用程序编程接口

C++ 通过c+;的lldb未解析断点+;应用程序编程接口,c++,debugging,lldb,llvm-c++-api,C++,Debugging,Lldb,Llvm C++ Api,我得到了可执行模块iCoreTest.exe,其中动态加载了库IRTest.rs。我想通过 LLDB C++ API调试. 当我通过lldb::SBTarget::Launch(…)在lldb下创建“iCoreTest.exe”进程时一切正常。使用fine,我的意思是我可以设置断点BreakpointCreateByLocation,当调试器停止时,从SBListener.WaitForEvent()获取事件 当我想连接到当前正在运行的进程时,问题就开始了 创建目标并附加到进程 m_debug

我得到了可执行模块iCoreTest.exe,其中动态加载了库IRTest.rs。我想通过<强> LLDB <强> C++ API调试. 当我通过lldb::SBTarget::Launch(…)在lldb下创建“iCoreTest.exe”进程时一切正常。使用fine,我的意思是我可以设置断点
BreakpointCreateByLocation
,当调试器停止时,从
SBListener.WaitForEvent()获取事件

当我想连接到当前正在运行的进程时,问题就开始了

  • 创建目标并附加到进程

    m_debugData->currentTarget=m_debugData>debugger.CreateTarget(executable.c_str());
    
    m_debugData->currentProcess = m_debugData>currentTarget.AttachToProcessWithName(m_debugData->listener, processName.c_str(), false, error);
    
  • 加载模块“IRTest.rs”

  • 之后,lldb上停止“ntdll.dll`DbgBreakPoint+1”

  • 我执行命令
    m_debugData->currentProcess.Continue()
  • 因此,ICoreTest.exe正在运行
  • 添加断点
    m_debugData->currentTarget.BreakpointCreateByllocation(“IRTest.st”,58)
  • 添加的断点不会被触发
  • 在此之后,我使用以下代码打印现有断点:

    void LLDBRunner::printBreakpoints()
        {
            for (int i = 0; i < m_debugData->currentTarget.GetNumBreakpoints(); i++)
            {
                auto bp = m_debugData->currentTarget.GetBreakpointAtIndex(i);
    
                for (int j = 0; j < bp.GetNumLocations(); j++)
                {
                    auto loc = bp.GetLocationAtIndex(j);
    
                    lldb::SBStream stream;
                    loc.GetDescription(stream, lldb::DescriptionLevel::eDescriptionLevelFull);
                    auto str = stream.GetData();
                }
            }
        }
    
    for (int i = 0; i < m_debugData->currentTarget.GetNumModules(); i++)
    {
        auto module = m_debugData->currentTarget.GetModuleAtIndex(i);
    
        auto moduleName = module.GetFileSpec().GetFilename();
    
        for (int j = 0; j < module.GetNumSections(); j++)
        {
            auto section = module.GetSectionAtIndex(j);
    
            auto sectionName = section.GetName();
            auto addr = section.GetLoadAddress(m_debugData->currentTarget);
            auto isValid = LLDB_INVALID_ADDRESS != addr;
    
            std::cout << "Module: " << moduleName << "; Section: " << sectionName << "; IsValid: " << isValid << std::endl;
        }
    }
    
    当我试图设置断点时

    m_debugData->currentTarget.BreakpointCreateByLocation("prog.cpp", 7);
    
    我得到了同样的结果

    1.1: where = a.exe`doSomething() + 6 at prog.cpp:7, address = a.exe[0x00401356], unresolved, hit count = 0 
    
    我的小研究:

    我比较了两个版本中的lldb行为:

  • 启动新流程(正常)
  • 连接到进程(断开)
  • 我在方法中发现了这一点

    lldb::break_id_t
    Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardware)
    

    load_addr = owner->GetAddress().GetOpcodeLoadAddress (&GetTarget());
    
    当我附加到进程时,返回版本中的LLDB_无效_地址

    调用堆栈:

    liblldb.dll!lldb_private::Process::CreateBreakpointSite(const std::shared_ptr<lldb_private::BreakpointLocation> & owner, bool use_hardware) Line 2094   C++
        liblldb.dll!lldb_private::BreakpointLocation::ResolveBreakpointSite() Line 523  C++
        liblldb.dll!lldb_private::BreakpointLocationList::AddLocation(const lldb_private::Address & addr, bool resolve_indirect_symbols, bool * new_location) Line 254  C++
        liblldb.dll!lldb_private::Breakpoint::AddLocation(const lldb_private::Address & addr, bool * new_location) Line 102 C++
        liblldb.dll!lldb_private::BreakpointResolver::AddLocation(lldb_private::Address loc_addr, bool * new_location) Line 214 C++
        liblldb.dll!lldb_private::BreakpointResolver::SetSCMatchesByLine(lldb_private::SearchFilter & filter, lldb_private::SymbolContextList & sc_list, bool skip_prologue, const char * log_ident) Line 184   C++
        liblldb.dll!lldb_private::BreakpointResolverFileLine::SearchCallback(lldb_private::SearchFilter & filter, lldb_private::SymbolContext & context, lldb_private::Address * addr, bool containing) Line 94 C++
        liblldb.dll!lldb_private::SearchFilter::DoModuleIteration(const lldb_private::SymbolContext & context, lldb_private::Searcher & searcher) Line 190  C++
        liblldb.dll!lldb_private::SearchFilter::Search(lldb_private::Searcher & searcher) Line 118  C++
        liblldb.dll!lldb_private::BreakpointResolver::ResolveBreakpoint(lldb_private::SearchFilter & filter) Line 62    C++
        liblldb.dll!lldb_private::Breakpoint::ResolveBreakpoint() Line 355  C++
        liblldb.dll!lldb_private::Target::AddBreakpoint(std::shared_ptr<lldb_private::Breakpoint> bp_sp, bool internal) Line 695    C++
        liblldb.dll!lldb_private::Target::CreateBreakpoint(std::shared_ptr<lldb_private::SearchFilter> & filter_sp, std::shared_ptr<lldb_private::BreakpointResolver> & resolver_sp, bool internal, bool request_hardware, bool resolve_indirect_symbols) Line 672  C++
        liblldb.dll!lldb_private::Target::CreateBreakpoint(const lldb_private::FileSpecList * containingModules, const lldb_private::FileSpec & file, unsigned int line_no, unsigned __int64 offset, lldb_private::LazyBool check_inlines, lldb_private::LazyBool skip_prologue, bool internal, bool hardware, lldb_private::LazyBool move_to_nearest_code) Line 411    C++
        liblldb.dll!lldb::SBTarget::BreakpointCreateByLocation(const lldb::SBFileSpec & sb_file_spec, unsigned int line, unsigned __int64 offset) Line 832  C++
        liblldb.dll!lldb::SBTarget::BreakpointCreateByLocation(const lldb::SBFileSpec & sb_file_spec, unsigned int line) Line 803   C++
        liblldb.dll!lldb::SBTarget::BreakpointCreateByLocation(const char * file, unsigned int line) Line 796   C++
        ConsoleApplication1.exe!Debugger::LLDBRunner::setBreakpoint(std::basic_string<char,std::char_traits<char>,std::allocator<char> > file, unsigned int line) Line 204  C++
        ConsoleApplication1.exe!main() Line 28  C++
    

    很难确定,但是python API和命令行API并不完全相同。在运行您请求的“实际”命令之前,它们都有自己的内部操作集。在Windows上调试肯定不如在其他平台上调试成熟,部分原因是还没有很多人使用它。我建议在lldb bug跟踪器中将此作为bug报告


    同时,您可以尝试手动创建一个目标,并在附加到进程之前设置断点。我不知道这是否可行,但在加载模块时动态解析断点与在放下断点时立即解析断点是两种不同的代码路径,因此,如果断点已经存在,它可能会起作用。

    很难确定,但是python API和命令行API并不完全相同。在运行您请求的“实际”命令之前,它们都有自己的内部操作集。在Windows上调试肯定不如在其他平台上调试成熟,部分原因是还没有很多人使用它。我建议在lldb bug跟踪器中将此作为bug报告


    同时,您可以尝试手动创建一个目标,并在附加到进程之前设置断点。我不知道这是否可行,但在加载模块时动态解析断点与在放下断点时立即解析断点是两种不同的代码路径,因此,如果断点已经存在,它可能会起作用。

    “我建议在lldb错误跟踪器上报告此错误。”我向管理员发送创建帐户的请求。“同时,也许您可以尝试手动创建一个目标,并在附加到进程之前设置断点”否,它没有帮助:)“我建议在lldb错误跟踪程序上报告此错误”我向管理员发送创建帐户的请求。同时,您可以尝试手动创建一个目标,并在附加到进程之前设置断点“否,它没有帮助:)
    lldb::break_id_t
    Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardware)
    
    load_addr = owner->GetAddress().GetOpcodeLoadAddress (&GetTarget());
    
    liblldb.dll!lldb_private::Process::CreateBreakpointSite(const std::shared_ptr<lldb_private::BreakpointLocation> & owner, bool use_hardware) Line 2094   C++
        liblldb.dll!lldb_private::BreakpointLocation::ResolveBreakpointSite() Line 523  C++
        liblldb.dll!lldb_private::BreakpointLocationList::AddLocation(const lldb_private::Address & addr, bool resolve_indirect_symbols, bool * new_location) Line 254  C++
        liblldb.dll!lldb_private::Breakpoint::AddLocation(const lldb_private::Address & addr, bool * new_location) Line 102 C++
        liblldb.dll!lldb_private::BreakpointResolver::AddLocation(lldb_private::Address loc_addr, bool * new_location) Line 214 C++
        liblldb.dll!lldb_private::BreakpointResolver::SetSCMatchesByLine(lldb_private::SearchFilter & filter, lldb_private::SymbolContextList & sc_list, bool skip_prologue, const char * log_ident) Line 184   C++
        liblldb.dll!lldb_private::BreakpointResolverFileLine::SearchCallback(lldb_private::SearchFilter & filter, lldb_private::SymbolContext & context, lldb_private::Address * addr, bool containing) Line 94 C++
        liblldb.dll!lldb_private::SearchFilter::DoModuleIteration(const lldb_private::SymbolContext & context, lldb_private::Searcher & searcher) Line 190  C++
        liblldb.dll!lldb_private::SearchFilter::Search(lldb_private::Searcher & searcher) Line 118  C++
        liblldb.dll!lldb_private::BreakpointResolver::ResolveBreakpoint(lldb_private::SearchFilter & filter) Line 62    C++
        liblldb.dll!lldb_private::Breakpoint::ResolveBreakpoint() Line 355  C++
        liblldb.dll!lldb_private::Target::AddBreakpoint(std::shared_ptr<lldb_private::Breakpoint> bp_sp, bool internal) Line 695    C++
        liblldb.dll!lldb_private::Target::CreateBreakpoint(std::shared_ptr<lldb_private::SearchFilter> & filter_sp, std::shared_ptr<lldb_private::BreakpointResolver> & resolver_sp, bool internal, bool request_hardware, bool resolve_indirect_symbols) Line 672  C++
        liblldb.dll!lldb_private::Target::CreateBreakpoint(const lldb_private::FileSpecList * containingModules, const lldb_private::FileSpec & file, unsigned int line_no, unsigned __int64 offset, lldb_private::LazyBool check_inlines, lldb_private::LazyBool skip_prologue, bool internal, bool hardware, lldb_private::LazyBool move_to_nearest_code) Line 411    C++
        liblldb.dll!lldb::SBTarget::BreakpointCreateByLocation(const lldb::SBFileSpec & sb_file_spec, unsigned int line, unsigned __int64 offset) Line 832  C++
        liblldb.dll!lldb::SBTarget::BreakpointCreateByLocation(const lldb::SBFileSpec & sb_file_spec, unsigned int line) Line 803   C++
        liblldb.dll!lldb::SBTarget::BreakpointCreateByLocation(const char * file, unsigned int line) Line 796   C++
        ConsoleApplication1.exe!Debugger::LLDBRunner::setBreakpoint(std::basic_string<char,std::char_traits<char>,std::allocator<char> > file, unsigned int line) Line 204  C++
        ConsoleApplication1.exe!main() Line 28  C++
    
    for (int i = 0; i < m_debugData->currentTarget.GetNumModules(); i++)
    {
        auto module = m_debugData->currentTarget.GetModuleAtIndex(i);
    
        auto moduleName = module.GetFileSpec().GetFilename();
    
        for (int j = 0; j < module.GetNumSections(); j++)
        {
            auto section = module.GetSectionAtIndex(j);
    
            auto sectionName = section.GetName();
            auto addr = section.GetLoadAddress(m_debugData->currentTarget);
            auto isValid = LLDB_INVALID_ADDRESS != addr;
    
            std::cout << "Module: " << moduleName << "; Section: " << sectionName << "; IsValid: " << isValid << std::endl;
        }
    }
    
    State changed unknown->stopped
    Module: a.exe; Section: .text; IsValid: 0
    Module: a.exe; Section: .data; IsValid: 0
    Module: a.exe; Section: .rdata; IsValid: 0
    Module: a.exe; Section: .eh_frame; IsValid: 0
    Module: a.exe; Section: .bss; IsValid: 0
    Module: a.exe; Section: .idata; IsValid: 0
    Module: a.exe; Section: .CRT; IsValid: 0
    Module: a.exe; Section: .tls; IsValid: 0
    Module: a.exe; Section: .debug_aranges; IsValid: 0
    Module: a.exe; Section: .debug_info; IsValid: 0
    Module: a.exe; Section: .debug_abbrev; IsValid: 0
    Module: a.exe; Section: .debug_line; IsValid: 0
    Module: a.exe; Section: .debug_frame; IsValid: 0