lldb10 can not hit break point on windows platform

I have a problem when download llvm10.0.1 and use lldb to debug my process on windows10 x64 platform. but with no debug point hit.
the command is

(lldb)target create “D:/code/MLExecuteTest.exe”
Current executable set to ‘D:/code/MLExecuteTest.exe’ (x86_64)
(lldb)br s -fE:/test/TestFunction.cpp -l1
Breakpoint 1: no locations(pending).
WARNING : Unable to resolve breakpoint to any actual locations.

Process 16228 launched ‘D:/code/MLExecuteTest.exe’
Process 16228 exited with status = 1(0x00000001)

my using detail is this below:
MLExecuteTest.exe is my process which will first compile the script TestFunction.cpp on debug mode and generate binary code in its memory, of course binary code has debug information, and then it use JIT ExecuteEngine to execute the binary code. I want to know, is llvm 10.0.1 support this using on windows platform. since before we use llvm5.0 on windows platform is OK, breakpoints can be hit. but while update version to 10.0.1, with same operation ,breakpoints can not be hit. so is llvm10.0.1 support or has any changes on this using on windows platform?

le wang

On Windows, LLVM is migrating to its own debug info reading code (the Native PDB reader) instead of relying on DIA (a Microsoft-provided Windows-only DLL for accessing debug info), so that might explain the difference between the older versions and the current.

I don’t know enough about LLDB’s model to understand how debug info for run-time generated code is handled. Certainly, at the time your transcript shows trying to set the breakpoint, the TestFunction.cpp code hasn’t yet been compiled, so it’s not a surprise that it cannot resolve the breakpoint at that time. When TestFunction.cpp gets JITted into code, LLDB would have to (1) be informed of the new code, (2) locate the debug info, and (3) try again to resolve the pending breakpoint. For me, there are a lot of unknowns in that sequence, so I cannot say whether it’s expected to work in the current version. If the JITted code is “loaded” dynamically the same way a DLL can be, then step 1 should work. But if the JIT code is brought into process memory some other way, then I think it’s likely the Windows debugger isn’t getting notified and thus cannot do steps 2 and 3.

Is it possible to reduce the problem down to a minimal sample program that reproduces the problem and to include it in a bug report?


As long as the location TestFunction.cpp:1 has a valid line in the PDB line tables, this breakpoint should be hit if there is debug info and the internal PDB parser is parsing things correctly. If you have debug info in your binary, _and_ if LLDB is able to locate your PDB file, then you should end up seeing a location if it was found. We can see this isn't happening:

(lldb)br s -fE:/test/TestFunction.cpp -l1
Breakpoint 1: no locations(pending).
WARNING : Unable to resolve breakpoint to any actual locations.

I would suggest debugging the LLDB and debugging:

uint32_t SymbolFilePDB::ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list);

This function is what turns the file (in "file_spec") and line (in "line") into a symbol context list (in "sc_list"). A SymbolContext is a class that defines a complete symbol file context for something. It contains a Module (executable), CompileUnit (if there is debug info for the source file), Function (if there is debug info for the function), Block (lexical block of the deepest lexical block that contains the start address for the file + line), LineEntry (source file and line number, which might have a line number greater than what you requested if there was no perfect match), and Symbol (symbol from the symbol table). We have a symbol context list, because you might have multiple matches for a given source file and line if your functions was inlined.

You might try just doing:

(lldb) b TestFunction.cpp:1

And seeing if that helps. If the debug information doesn't contain the exact same path of "E:/test/TestFunction.cpp", it might not set the breapoint if the path in the debug info contains symlinks or is a relative path.

Does anyone know if the "pdb" file shows up when doing "image list" in LLDB? On mac if we have a stand alone debug info file, we show it below the executable:

(lldb) target create "/tmp/a.out"
Current executable set to '/tmp/a.out' (x86_64).
(lldb) image list a.out
[ 0] E76A2647-AFB4-3950-943A-CB1D701B7C07 0x0000000100000000 /tmp/a.out

If you do a "image list" on your executable, it would be interesting to see if the pdb file shows up in this output.

Greg Clayton

Hi, all:
Thanks for your answer. Maybe my description is not clear enough. MLExecuteTest.exe is just a shell to compile and execute TestFunctin.cpp, the step is below:

  1. call llvm function to compile TestFunction.cpp, this will create module ,function, block, instruction, and generate binary code with debug info;
  2. it uses JIT ExecuteEnginie to execute the binary code.
    and what I use lldb to debug is the binary code generated from TestFunction.cpp. So I am not concerned about the pdb of MLExecuteTest.exe.

According to your suggestion, I have debug lldb source code, set breakpoint in SymbolFilePDB::ResolveSymbolContext, but not come in this function. Since I think my debug info is all generated by llvm tegother with IR in the first phrase, which is all contained in binary code. I don’t know in the second phrase, while JIT load binary code to generate execute process, weather JIT will meanwhile generate some other debug info in PDB forms on windows platform, if so, which library in llvm do this work, and how does lldb load these PDB symbols. Because if PDB needs to be generated, maybe this is what I missed.

On the other hand, I’ve debug the lldb to see what happens in CompileUnit::ResolveSymbolContext, and found that every debug line can be parsed from DWARFDebugLine.cpp, then the function FindLineEntryIndexByFileIndex in LinTable.cpp will find whether the file_addr of line entry is contained in file addresses of section list(I don’t know the reason why lldb do this). But the result is the file_addr of each line can not be found from the section list addresses. So at last lines are not found, breakpoint not hit.

I have added some code in notifyObjectLoaded function from GDBRegistrationListener.cpp to store the middle ELF data. Sections and debug_line details can be seen by the readelf linux command. Can you help me to analyse the debug info in ELF, check whether there is anything wrong in debug info, which causes breakpoints not to be hit.
the TestFunction.cpp and its ELF data is brought in attachment.

le wang

Greg Clayton <clayborg@gmail.com> 于2020年10月20日周二 上午7:23写道:

ELFData.txt (2.41 KB)

TestFunction.cpp (112 Bytes)

So the good news is the DWARF seems to be valid.

I think LLDB is having problems with this ELF file because it is an object file (e_type == ET_REL) or because it has no program headers.

There were some changes made to LLDB where we would put any section headers that were contained in program headers inside of a section named for the program headers. So you will normally end up with sections in LLDB like:


Note how any section that is contained within a program header is contained within a PT_LOAD[N] section.

If I load your ELF binary, I can set a breakpoint:

(lldb) b TestFunction.cpp:1
Breakpoint 1: where = ELFData.txt`::20000() + 4 at TestFunction.cpp:1:7, address = 0x0000000000000004

I can also view the line table that LLDB was able to parse:

(lldb) target modules dump line-table TestFunction.cpp
Line table for /test/E:/test/TestFunction.cpp in `ELFData.txt
0x0000000000000000: E:/test/TestFunction.cpp
0x0000000000000004: E:/test/TestFunction.cpp:1:7
0x000000000000000c: E:/test/TestFunction.cpp:2:7
0x0000000000000014: E:/test/TestFunction.cpp:3:7
0x000000000000001c: E:/test/TestFunction.cpp:4:7
0x000000000000002a: E:/test/TestFunction.cpp:4:7

But if we look at the sections, we see the sections had their addresses changed. If we look at what is in the ELF file:

$ elf.py /tmp/ELFData.txt
ELF: /tmp/ELFData.txt (x86_64)
ELF Header:
e_ident[EI_MAG0 ] = 0x7f
e_ident[EI_MAG1 ] = 0x45 ‘E’
e_ident[EI_MAG2 ] = 0x4c ‘L’
e_ident[EI_MAG3 ] = 0x46 ‘F’
e_ident[EI_CLASS ] = 0x02 ELFCLASS64
e_ident[EI_DATA ] = 0x01 ELFDATA2LSB
e_ident[EI_VERSION ] = 0x01
e_ident[EI_OSABI ] = 0x00 ELFOSABI_NONE
e_ident[EI_ABIVERSION] = 0x00
e_type = 0x0001 ET_REL
e_machine = 0x003e EM_X86_64
e_version = 0x00000001
e_entry = 0x0000000000000000
e_phoff = 0x0000000000000000
e_shoff = 0x0000000000000568
e_flags = 0x00000000
e_ehsize = 0x0040
e_phentsize = 0x0000
e_phnum = 0x0000
e_shentsize = 0x0040
e_shnum = 0x0011
e_shstrndx = 0x0001

Section Headers:
Index sh_name sh_type sh_flags sh_addr sh_offset sh_size sh_link sh_info sh_addr_a sh_entsize
======= ---------- ----------------- ------------------ ------------------ ------------------ ------------------ ---------- ---------- ------------------ ------------------
[ 0] 0x00000000 SHT_NULL 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x00000000 0x00000000 0x0000000000000000 0x0000000000000000
[ 1] 0x0000008b SHT_STRTAB 0x0000000000000000 0x0000000000000000 0x00000000000004c0 0x00000000000000a1 0x00000000 0x00000000 0x0000000000000001 0x0000000000000000 .strtab
[ 2] 0x0000000f SHT_PROGBITS 0x0000000000000006 0x00000137f1030000 0x0000000000000040 0x000000000000002a 0x00000000 0x00000000 0x0000000000000010 0x0000000000000000 .text ( SHF_ALLOC SHF_EXECINSTR )
[ 3] 0x0000003f SHT_PROGBITS 0x0000000000000030 0x0000000000000000 0x000000000000006a 0x000000000000003e 0x00000000 0x00000000 0x0000000000000001 0x0000000000000001 .debug_str ( SHF_MERGE SHF_STRINGS )
[ 4] 0x00000001 SHT_PROGBITS 0x0000000000000000 0x0000000000000000 0x00000000000000a8 0x0000000000000043 0x00000000 0x00000000 0x0000000000000001 0x0000000000000000 .debug_abbrev
[ 5] 0x0000004f SHT_PROGBITS 0x0000000000000000 0x0000000000000000 0x00000000000000eb 0x000000000000008d 0x00000000 0x00000000 0x0000000000000001 0x0000000000000000 .debug_info
[ 6] 0x0000004a SHT_RELA 0x0000000000000000 0x0000000000000000 0x0000000000000310 0x0000000000000150 0x00000010 0x00000005 0x0000000000000008 0x0000000000000018 .rela.debug_info
[ 7] 0x0000002f SHT_PROGBITS 0x0000000000000000 0x0000000000000000 0x0000000000000178 0x000000000000001c 0x00000000 0x00000000 0x0000000000000001 0x0000000000000000 .debug_pubnames
[ 8] 0x0000002a SHT_RELA 0x0000000000000000 0x0000000000000000 0x0000000000000460 0x0000000000000018 0x00000010 0x00000007 0x0000000000000008 0x0000000000000018 .rela.debug_pubnames
[ 9] 0x0000001a SHT_PROGBITS 0x0000000000000000 0x0000000000000000 0x0000000000000194 0x0000000000000026 0x00000000 0x00000000 0x0000000000000001 0x0000000000000000 .debug_pubtypes
[ 10] 0x00000015 SHT_RELA 0x0000000000000000 0x0000000000000000 0x0000000000000478 0x0000000000000018 0x00000010 0x00000009 0x0000000000000008 0x0000000000000018 .rela.debug_pubtypes
[ 11] 0x0000005b SHT_PROGBITS 0x0000000000000000 0x0000000000000000 0x00000000000001ba 0x0000000000000000 0x00000000 0x00000000 0x0000000000000001 0x0000000000000000 .note.GNU-stack
[ 12] 0x00000081 SHT_ARM_EXIDX 0x0000000000000002 0x00000137f1040000 0x00000000000001c0 0x0000000000000038 0x00000000 0x00000000 0x0000000000000008 0x0000000000000000 .eh_frame ( SHF_ALLOC )
[ 13] 0x0000007c SHT_RELA 0x0000000000000000 0x0000000000000000 0x0000000000000490 0x0000000000000018 0x00000010 0x0000000c 0x0000000000000008 0x0000000000000018 .rela.eh_frame
[ 14] 0x00000070 SHT_PROGBITS 0x0000000000000000 0x0000000000000000 0x00000000000001f8 0x0000000000000052 0x00000000 0x00000000 0x0000000000000001 0x0000000000000000 .debug_line
[ 15] 0x0000006b SHT_RELA 0x0000000000000000 0x0000000000000000 0x00000000000004a8 0x0000000000000018 0x00000010 0x0000000e 0x0000000000000008 0x0000000000000018 .rela.debug_line
[ 16] 0x00000093 SHT_SYMTAB 0x0000000000000000 0x0000000000000000 0x0000000000000250 0x00000000000000c0 0x00000001 0x00000007 0x0000000000000008 0x0000000000000018 .symtab

We can see the .text section has an address of 0x00000137f1030000, but in LLDB it gets set to zero:

(lldb) image dump sections
Dumping sections for 1 modules.
Sections for ‘/tmp/ELFData.txt’ (x86_64):
SectID Type File Address Perm File Off. File Size Flags Section Name

0x00000001 regular — 0x000004c0 0x000000a1 0x00000000 ELFData.txt…strtab
0x00000002 code [0x0000000000000000-0x000000000000002a) r-x 0x00000040 0x0000002a 0x00000006 ELFData.txt…text
0x00000003 dwarf-str — 0x0000006a 0x0000003e 0x00000030 ELFData.txt…debug_str
0x00000004 dwarf-abbrev — 0x000000a8 0x00000043 0x00000000 ELFData.txt…debug_abbrev
0x00000005 dwarf-info — 0x000000eb 0x0000008d 0x00000000 ELFData.txt…debug_info
0x00000006 elf-relocation-entries — 0x00000310 0x00000150 0x00000000 ELFData.txt…rela.debug_info
0x00000007 dwarf-pubnames — 0x00000178 0x0000001c 0x00000000 ELFData.txt…debug_pubnames
0x00000008 elf-relocation-entries — 0x00000460 0x00000018 0x00000000 ELFData.txt…rela.debug_pubnames
0x00000009 dwarf-pubtypes — 0x00000194 0x00000026 0x00000000 ELFData.txt…debug_pubtypes
0x0000000a elf-relocation-entries — 0x00000478 0x00000018 0x00000000 ELFData.txt…rela.debug_pubtypes
0x0000000b regular — 0x000001ba 0x00000000 0x00000000 ELFData.txt…note.GNU-stack
0x0000000c eh-frame [0x0000000000000030-0x0000000000000068) r-- 0x000001c0 0x00000038 0x00000002 ELFData.txt…eh_frame
0x0000000d elf-relocation-entries — 0x00000490 0x00000018 0x00000000 ELFData.txt…rela.eh_frame
0x0000000e dwarf-line — 0x000001f8 0x00000052 0x00000000 ELFData.txt…debug_line
0x0000000f elf-relocation-entries — 0x000004a8 0x00000018 0x00000000 ELFData.txt…rela.debug_line
0x00000010 elf-symbol-table — 0x00000250 0x000000c0 0x00000000 ELFData.txt…symtab

So I am not sure if this is due to the program header changes in LLDB, or due to the fact that this file is basically a .o file with relocations (the ELF header shows the e_type is ET_REL).

If you have an older LLDB that did work, it would be interesting to load this ELF file into that LLDB and see what the “image dump sections” looks like.

Thanks, I will take a look.

Greg Clayton <clayborg@gmail.com> 于2020年10月21日周三 上午2:50写道: