[lldb-dev] How to set source line breakpoint using BreakpointCreateByLocation?

Jeffrey Tan via lldb-dev lldb-dev at lists.llvm.org
Sat Mar 5 11:47:31 PST 2016


Ooops, I accidentally dropped lldb mail list.
I have chatted this long relative path issue with our buck build team, they
seem to do some kind of post-processing for the symbol files but failed to
run another scripts to resolve the processed paths back into absolute path.
And they are unable to fix this in short time. :-(

I am building a workaround for this issue:
I am building a middle indirection map between debugger UI and lldb.
Whenever I enumerate a SBFileSpec a source line, I get the source file long
relative path from it and add basepath of the build project then normalize
into an absolute path, then store absolute_path->SBFileSpec mapping into
the map, then send the absolute path to debugger UI. When the debugger UI
is trying to set source line breakpoint, I got the absolute path back from
debugger UI and use the middle indirection map to find corresponding
SBFileSpec for that source file. Finally, I used the SBFileSpec to set
source line breakpoint.
The assumption is that as long as I used the same SBFileSpec from lldb, I
should use it to set source line breakpoint successfully.
However, it turns out this still does not work. The breakpoints are listed
as pending:

break list
Current breakpoints:
1: file =
'.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/App/main.m',
line = 9, locations = 0 (pending)
2: file =
'.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m',
line = 20, locations = 0 (pending)

Questions:
Isn't lldb treating this long relative path as *absolute path* so as long
as this long path is used to set breakpoint it should work? Any idea why
this workaround approach does not work?

Jeffrey

On Wed, Jan 6, 2016 at 8:47 AM, Jeffrey Tan <jeffrey.fudan at gmail.com> wrote:

> Nevermind, I do not know why "GetSelectedTarget().
> BreakpointCreateByLocation("EATAnimatedView.m", line)" does not work for
> me last October. I tried it again, it works now.
> I will see if I can figure out the weird relative location path in symbol
> file issue.
>
> Thanks!
>
> On Tue, Jan 5, 2016 at 3:38 PM, Jeffrey Tan <jeffrey.fudan at gmail.com>
> wrote:
>
>> Sorry for the late response. I finally had time to come back to this
>> issue.
>>
>> Can anyone help me with the "self.debugger.GetSelectedTarget().
>> BreakpointCreateByLocation("EATAnimatedView.m", line)" not working
>> issue? Does it suppose to work? I can reproduce it pretty easily in a small
>> python script.
>>
>> I found the following lldb test that uses this API:
>>
>> http://www.opensource.apple.com/source/lldb/lldb-69/test/lang/objc/objc-stepping/TestObjCStepping.py
>>
>> So it seems that this should work. Am I doing something wrong? I am
>> importing the Xcode's lldb by following:
>> developer_dir = subprocess.check_output(['xcode-select', '--print-path'])
>>     lldb_pythonpath = os.path.join(
>>         developer_dir.strip(),
>> '../SharedFrameworks/LLDB.framework/Resources/Python')
>>     sys.path.append(lldb_pythonpath)
>>
>> For the weird long path issue, I will follow-up with our build team, but
>> definitely needs to resolve the BreakpointCreateByLocation() can't be
>> called issue first.
>>
>> Thanks for any help!
>> Jeffrey
>>
>> On Thu, Oct 8, 2015 at 10:46 AM, Greg Clayton <gclayton at apple.com> wrote:
>>
>>>
>>> > On Oct 8, 2015, at 10:25 AM, Jeffrey Tan <jeffrey.fudan at gmail.com>
>>> wrote:
>>> >
>>> > Thanks Greg. Here is the info:
>>> > (lldb) br list --verbose
>>> > Current breakpoints:
>>> > 1: file = 'EATAnimatedView.m', line = 21
>>> >     1.1:
>>> >       module =
>>> /Users/jeffreytan/Library/Developer/CoreSimulator/Devices/12E85C41-A74F-45E1-8440-E7D08D8EB1FA/data/Containers/Bundle/Application/3BA10AF8-9B18-4FD8-8C76-EA25DE2F37E6/MPKEats.app/MPKEats
>>> >       compile unit = EATAnimatedView.m
>>> >       function = -[EATAnimatedView
>>> initWithFrame:imageNames:animationDuration:repeatCount:touchEnabled:]
>>> >       location =
>>> ./////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m:21
>>> >       address = 0x0000000103deae42
>>> >       resolved = true
>>> >       hit count = 0
>>> >
>>>
>>> Wow that is a lot of redundant ////'s. You should fix your build system
>>> to not do this for one, but I agree we need to deal with this.
>>>
>>> You can modify the following function:
>>>
>>> void
>>> FileSpec::RemoveBackupDots (const ConstString &input_const_str,
>>> ConstString &result_const_str);
>>>
>>> To remove the redundant slashes and it might make things work. The thing
>>> that really worries me is that you still have a relative location in your
>>> sources:
>>>
>>>
>>> "./////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m:21"
>>>
>>>
>>> This should have been resolved from the DWARF using DW_AT_comp_dir. What
>>> should happen is your DWARF should have a compile unit like:
>>>
>>>
>>> 0x0000000b: DW_TAG_compile_unit [1] *
>>>             DW_AT_producer( "Apple LLVM version 7.x.x" )
>>>             DW_AT_language( DW_LANG_ObjC )
>>>             DW_AT_name(
>>> "./Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m" )
>>>             DW_AT_stmt_list( 0x00000000 )
>>>             DW_AT_comp_dir( "/tmp/build/foo/bar" )
>>>             DW_AT_low_pc( 0x0000000100000b50 )
>>>             DW_AT_high_pc( 0x0000000100000e62 )
>>>
>>>
>>> So if the DW_AT_name of your compile unit is relative, we should have a
>>> DW_AT_comp_dir that is absolute. Put the two together and we should have a
>>> complete path that works.
>>>
>>> Can you send me your ELF file that contains the DWARF so I can look at
>>> it?
>>>
>>> > I think we should fix this full path matching issue. It is totally
>>> reasonable for debugger user to move source file from build location to
>>> another place. Also, this needs to be supported for source server scenario.
>>> As long as the source file's checksum matches what recorded in symbol file
>>> we should match it.
>>> >
>>> > I still need to figure out why
>>> "self.debugger.GetSelectedTarget().BreakpointCreateByLocation("EATAnimatedView.m",
>>> line)" not working issue. The callstack seems to indicate I passed wrong
>>> number of arguments into it.
>>>
>>> This might be a swig type map issue where "line" in the python is a long
>>> and we don't know how to convert it to be passed to a uint32_t. We have
>>> seen such issues if the past where if you variable is a long, integer or
>>> other, it might not convert to uint32_t correctly...
>>>
>>>
>>> >
>>> > Jeffrey
>>> >
>>> > On Thu, Oct 8, 2015 at 9:46 AM, Greg Clayton <gclayton at apple.com>
>>> wrote:
>>> > > On Oct 7, 2015, at 8:31 PM, Jeffrey Tan via lldb-dev <
>>> lldb-dev at lists.llvm.org> wrote:
>>> > >
>>> > > Hi,
>>> > >
>>> > > I am writing a python script to set source line breakpoint in ObjC
>>> on Mac OSX. But
>>> self.debugger.GetSelectedTarget().BreakpointCreateByLocation("EATAnimatedView.m",
>>> line) always fail. Any ideas?
>>> >
>>> > As long as you have a selected target, this should work as long as you
>>> have debug info that matches.
>>> > >
>>> > > Also, can I use full path instead of file basename?
>>> >
>>> > Yes you can, but it must match exactly if you use the full path.
>>> >
>>> > > In lldb, I found "b
>>> /Users/jeffreytan/fbsource/fbobjc/Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m:21"
>>> will fail to bind but "b EATAnimatedView.m:21" will succeed.
>>> >
>>> > This is usually because you have a makefile build system that is
>>> creating debug info that doesn't contain a path that matches. When you
>>> launch a compiler, it can often end up with different paths than what you
>>> think you have. So set the breakpoint by basename first, then do:
>>> >
>>> > (lldb) b main.c:12
>>> > Breakpoint 1: where = a.out`main + 70 at main.c:12, address =
>>> 0x0000000100000b96
>>> > (lldb) breakpoint list --verbose
>>> > Current breakpoints:
>>> > 1: file = 'main.c', line = 12
>>> >     1.1:
>>> >       module = /Volumes/work/gclayton/Documents/src/args/a.out
>>> >       compile unit = main.c
>>> >       function = main
>>> >       location = /Volumes/work/gclayton/Documents/src/args/main.c:12
>>> >       address = a.out[0x0000000100000b96]
>>> >       resolved = false
>>> >       hit count = 0
>>> >
>>> >
>>> > You will see the full path to your source file in the "location"
>>> value. You will probably notice that the path is different. We try to take
>>> care of removing and extra "../useless_dir" things from the paths and still
>>> make things match, but you might have a case that we aren't handling. Let
>>> me know what you see when you set the breakpoint by basename.
>>> >
>>> >
>>> > > Traceback (most recent call last):
>>> > >   File
>>> "/Users/jeffreytan/fbsource/fbobjc/Tools/Nuclide/pkg/nuclide/debugger/lldb/scripts/chromedebugger.py",
>>> line 69, in _generate_response
>>> > >     params=message.get('params', {}),
>>> > >   File
>>> "/Users/jeffreytan/fbsource/fbobjc/Tools/Nuclide/pkg/nuclide/debugger/lldb/scripts/handler.py",
>>> line 42, in handle
>>> > >     return self._domains[domain_name].handle(method_name, params)
>>> > >   File
>>> "/Users/jeffreytan/fbsource/fbobjc/Tools/Nuclide/pkg/nuclide/debugger/lldb/scripts/handler.py",
>>> line 106, in handle
>>> > >     return self._handlers[method](params)
>>> > >   File
>>> "/Users/jeffreytan/fbsource/fbobjc/Tools/Nuclide/pkg/nuclide/debugger/lldb/scripts/handler.py",
>>> line 56, in _handler_wrapper
>>> > >     ret = func(self, params)
>>> > >   File
>>> "/Users/jeffreytan/fbsource/fbobjc/Tools/Nuclide/pkg/nuclide/debugger/lldb/scripts/debugger.py",
>>> line 248, in setBreakpointByUrl
>>> > >     int(params['lineNumber']) + 1)
>>> > >   File
>>> "/Users/jeffreytan/fbsource/fbobjc/Tools/Nuclide/pkg/nuclide/debugger/lldb/scripts/debugger.py",
>>> line 283, in _set_breakpoint_by_filespec
>>> > >     breakpoint =
>>> self.debugger.GetSelectedTarget().BreakpointCreateByLocation(filespec, line)
>>> > >   File
>>> "/Applications/Xcode.app/Contents/Developer/../SharedFrameworks/LLDB.framework/Resources/Python/lldb/__init__.py",
>>> line 8650, in BreakpointCreateByLocation
>>> > >     return _lldb.SBTarget_BreakpointCreateByLocation(self, *args)
>>> > > NotImplementedError: Wrong number of arguments for overloaded
>>> function 'SBTarget_BreakpointCreateByLocation'.
>>> > >   Possible C/C++ prototypes are:
>>> > >     BreakpointCreateByLocation(lldb::SBTarget *,char const
>>> *,uint32_t)
>>> > >     BreakpointCreateByLocation(lldb::SBTarget *,lldb::SBFileSpec
>>> const &,uint32_t)
>>> > > _______________________________________________
>>> > > lldb-dev mailing list
>>> > > lldb-dev at lists.llvm.org
>>> > > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>>> >
>>> >
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20160305/647405a0/attachment-0001.html>


More information about the lldb-dev mailing list