lldb unresolved breakpoint via c++ api

1

I have got executable module iCoreTest.exe, wich dynamicly loaded library IRTest.rs. I want to debug it via lldb c++ api.

When I create "iCoreTest.exe" process under lldb throug lldb::SBTarget::Launch(..); everything works fine. With fine, I mean I can set breakpoints BreakpointCreateByLocation and when the debugger stops on it get the event from SBListener.WaitForEvent();

Problems begins when I want to attach to the currently running process.

  1. Create target and attach to process

    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. Load module "IRTest.rs"

      auto module = m_debugData->currentTarget.AddModule("IRTest.rs", "i386-pc-windows-msvc", nullptr);
    
  3. After that lldb stops on "ntdll.dll`DbgBreakPoint + 1"

  4. I execute command m_debugData->currentProcess.Continue();
  5. So, ICoreTest.exe is running..
  6. Add breakpoint m_debugData->currentTarget.BreakpointCreateByLocation("IRTest.st", 58);
  7. The added breakpoint does not triggered

After this I print the existing breakpoints using the following code:

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

And output was:

1.1: where = IRTest.rs`Add + 421 at IRTest.st:58, address = IRTest.rs[0x10001525], unresolved, hit count = 0

Which means my breakpoint is unresolved..Why? :)

Also! When i use lldb command line breakpoint is resolved, and working:

(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:

I write a simple program wich reproduce bug

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

Compile it..

gcc prog.cpp -g -O0

When i`m trying to set break point

m_debugData->currentTarget.BreakpointCreateByLocation("prog.cpp", 7);

I get same result

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

My little research:

I compare lldb behavior in two versions:

  1. Launch new process(is ok)
  2. Attach to process(broken)

I found that in method

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

line..

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

return LLDB_INVALID_ADDRESS in version when I attach to process.

CallStack:

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

UPDATE 2:

I print 'a.exe' module sections using the following code:

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

An output was:

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
c++
debugging
lldb
llvm-c++-api
asked on Stack Overflow Sep 22, 2016 by Nikita Karasyev • edited Sep 23, 2016 by Nikita Karasyev

1 Answer

0

It's hard to say with certainty, but the python APIs and the command line apis are not entirely the same. They both have their own set of things they do internally before running the "actual" command you requested. Debugging on Windows is definitely not as mature as on other platforms, in part because there are not a lot of people using it yet. I would suggest reporting this as a bug on the lldb bug tracker.

In the meantime, maybe you can try creating a target manually, and setting the breakpoint BEFORE you attach to the process. I don't know if this will work, but resolving a breakpoint dynamically when a module is loaded, versus trying to resolve it immediately when you drop the breakpoint down are two different codepaths, so it's possible it will work if the breakpoint is already there.

answered on Stack Overflow Sep 22, 2016 by Zachary Turner

User contributions licensed under CC BY-SA 3.0