2016-09-22 50 views
1

我有可執行模塊iCoreTest.exe,這是動態加載庫IRTest.rs。我想通過lldb C++ api進行調試。lldb未解決的斷點通過C++ api

當我創建「iCoreTest.exe」進程下LLDB通過量LLDB :: SBTarget ::啓動(..);一切工作正常。罰款,我的意思是我可以設置斷點BreakpointCreateByLocation,當調試器停下來從它得到事件SBListener.WaitForEvent();

問題開始時,我想要附加到當前正在運行的進程。

  1. 創建目標,重視處理

    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); 
    
  2. 加載模塊 「IRTest.rs」

    auto module = m_debugData->currentTarget.AddModule("IRTest.rs", "i386-pc-windows-msvc", nullptr); 
    
  3. 「ntdll.dll`DbgBreakPoint是LLDB停止後+ 1「

  4. 我執行命令m_debugData->currentProcess.Continue();
  5. 所以,ICoreTest.exe運行..
  6. 添加斷點m_debugData->currentTarget.BreakpointCreateByLocation("IRTest.st", 58);
  7. 添加的斷點不觸發

這個我打印使用現有的斷點後以下代碼:

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(); 
      } 
     } 
    } 

輸出結果爲:

1.1:其中= IRTest.rs`Add + 421 IRTest.st:58,地址= IRTest.rs [0x10001525],未解決的,命中計數= 0

這意味着我的斷點unresolved..Why? :)

另外! 當我使用LLDB命令行斷點解決,工作:

(lldb) attach -p 17448 
Process 17448 stopped 
* thread #1: tid = 0x0ae0, 0x77bc8d21 ntdll.dll`DbgBreakPoint + 1, stop reason = Exception 0x80000003 encountered at address 0x77bc8d20 
    frame #0: 0x77bc8d21 ntdll.dll`DbgBreakPoint + 1 
ntdll.dll`DbgBreakPoint: 
-> 0x77bc8d21 <+1>: retl 
    0x77bc8d22 <+2>: int3 
    0x77bc8d23 <+3>: int3 
    0x77bc8d24 <+4>: int3 

Executable module set to "iCoreTest.exe". 
Architecture set to: i386-pc-windows-msvc. 
(lldb) b IRTest.st:58 
Breakpoint 1: where = IRTest.rs`Add + 421 at IRTest.st:58, address = 0x07ca1525 
(lldb) b 
Current breakpoints: 
1: file = 'IRTest.st', line = 58, exact_match = 0, locations = 1, resolved = 1, hit count = 0 
    1.1: where = IRTest.rs`Add + 421 at IRTest.st:58, address = 0x07ca1525, resolved, hit count = 0 

(lldb) c 
Process 17448 resuming 
Process 17448 stopped 
* thread #6: tid = 0x2560, 0x07ca1525 IRTest.rs`Add(X1=2, X2=42, X3=(RANGE = 1, MIN_SCALE = -4095, MAX_SCALE = 4095)) + 421 at IRTest.st:58, stop reason = breakpoint 1.1 
    frame #0: 0x07ca1525 IRTest.rs`Add(X1=2, X2=42, X3=(RANGE = 1, MIN_SCALE = -4095, MAX_SCALE = 4095)) + 421 at IRTest.st:58 
    55    i, j : INT; 
    56  END_VAR 
    57 
-> 58   tmpInteg(); 
    59 
    60 
    61 
(lldb) 

UPDATE:

我寫一個簡單的程序至極重現錯誤

prog.cpp

#include <cstdio> 

void doSomething(void); 

void doSomething(void) 
{ 
    int loop = 0; 
    loop += 1; 
    loop += 2; 
    loop += 3; 
} 

int main(void)` 
{ 
    printf("start \n"); 

    while(1) 
    { 
    doSomething(); 
    } 

    return 0; 
} 

編譯它..

gcc prog.cpp -g -O0 

當我真的試圖設置斷點

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行爲:

  1. 推出新工藝(是確定)
  2. 附加到進程(碎)

我發現,在法

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

線。在

load_addr = owner->GetAddress().GetOpcodeLoadAddress (&GetTarget()); 

回報LLDB_INVALID_ADDRESS版本,當我附加到過程。

調用堆棧:

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++ 

更新2:

我打印使用以下代碼 'A.EXE' 模塊部分:

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 

回答

0

很難說可以肯定,但是python API和命令行apis並不完全相同。在運行您請求的「實際」命令之前,他們都有自己的一套內部操作。在Windows上進行調試絕對不像其他平臺上的成熟,部分原因是現在還沒有很多人使用它。我建議將此報告爲lldb錯誤跟蹤程序的錯誤。

在此期間,也許您可​​以嘗試手動創建目標,並在您附加到過程之前設置斷點。我不知道這是否會起作用,但是在加載模塊時動態地解析斷點,而不是在你放下斷點時立即解決斷點是兩種不同的代碼路徑,所以如果斷點已經存在,它可能會工作。

+0

「我建議將此報告爲lldb錯誤跟蹤程序的錯誤」 我向管理員發送創建帳戶的請求。 「與此同時,也許你可以嘗試手動創建一個目標,並在你附加到過程之前設置斷點」 不,它沒有幫助:) –