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

Jeffrey Tan via lldb-dev lldb-dev at lists.llvm.org
Tue Mar 8 10:49:29 PST 2016


Thanks for the info. I will use a solution similar to that.

Jeffrey

On Tue, Mar 8, 2016 at 10:41 AM, Greg Clayton <gclayton at apple.com> wrote:

>
> > On Mar 7, 2016, at 5:27 PM, Jeffrey Tan <jeffrey.fudan at gmail.com> wrote:
> >
> > Thanks for the info, I will debug this.
> > One more quick question related to this: in full path breakpoint
> case(IDE scenario), do we compare both file name and directory path exact
> match and bind breakpoint successfully? I ask this because of the
> breakpoint issue I found:
> > 1. I have a symbolic link folder "/home/jeffreytan/foo/" which points to
> "/data/users/jeffreytan/bar/foo".
> > 2. If I built cpp file in /home/jeffreytan/foo/, and try to set
> breakpoint using real path "b /data/users/jeffreytan/bar/foo/main.cpp:10"
> it will fail to bind.
> > 3. While "b /home/jeffreytan/foo//main.cpp:10" binds fine, vise verse.
>
> Yep, that will fail for the reason that "/home/jeffreytan/foo" won't match
> "/data/users/jeffreytan/bar/foo" and we don't resolve paths on debug info
> because of the cost as we mentioned before.
>
> >
> > I can't control how users open/build file in our IDE, they may choose to
> open/build from symbolic link folder or real path folder. What is the
> general suggestion to deal with symbolic link differences?
>
> There isn't a good one right now. One idea is to try and track the project
> directory in your IDE, like "/home/jeffreytan/foo", and note that this is
> the base directory. Then have the IDE always set the breakpoint by basename
> ("main.cpp") and then filter the results out based on where the file is in
> the project directory. So if you have your main file in your project
> directory as "src/main.cpp", you would set a breakpoint in main.cpp, and
> then look at the locations that the breakpoint had and disable any
> locations that don't have a matching parent directory of "src"...
>
> Greg
>
> >
> > Jeffrey
> >
> >
> >
> >
> > On Mon, Mar 7, 2016 at 4:25 PM, Greg Clayton <gclayton at apple.com> wrote:
> >
> > > On Mar 7, 2016, at 4:08 PM, Jeffrey Tan <jeffrey.fudan at gmail.com>
> wrote:
> > >
> > > Hi Greg,
> > >
> > > I am not sure if I understand the behavior here: the long relative
> file path from our build system does *not* exist on file system, do you
> mean lldb will always try to resolve this relative path to a *real* file on
> file system using stat() call?
> >
> > No it doesn't do that and that is why you path remains as is.
> >
> > > And it will fail to bind the breakpoint if can't find the resolved
> file path?
> >
> > No it shouldn't if you set it by basename. If it does fail to set the
> breakpoint using "EATAnimatedView.m" as the filename, then it is a bug.
> >
> > >
> > > Per my testing, I was able to use #1. "b EATAnimatedView.m:33" to bind
> breakpoint, but not:
> > > #2, "b
> .//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m:20"
> >
> > That is interesting, and you will need to track down why this is
> happening. Obviously we are expecting this kind of path and something is
> going wrong.
> >
> > > break list --verbose
> > > Current breakpoints:
> > > 2: file =
> './/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m',
> line = 20
> > >
> > > 3: file = 'EATAnimatedView.m', line = 33
> > >     3.1:
> > >       module =
> /Users/jeffreytan/Library/Developer/CoreSimulator/Devices/32967F60-A4C3-43DC-ACA8-92D819413362/data/Containers/Bundle/Application/96DA24F5-E35D-402F-B4B7-1C5BBD40B270/MPKEats.app/MPKEats
> > >       compile unit = EATAnimatedView.m
> > >       function = -[EATAnimatedView
> initWithFrame:imageNames:animationDuration:repeatCount:touchEnabled:]
> > >       location =
> ./////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m:33
> > >       address = 0x000000010a1ff798
> > >       resolved = true
> > >       hit count = 0
> > >
> > > Do you mean #2 should work?
> >
> > I would expect #2 to work, but not surprised it doesn't.
> >
> > > I think I am a bit vague on how source breakpoint is supposed to work.
> What is the algorithm to successfully bind breakpoint here?
> >
> > What we currently do is break all file paths up into a basename
> (EATAnimatedView.m) and a directory
> (.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View).
> >
> > We break up filenames like this because the user will rarely type full
> paths in commands. IDEs will often give us full paths to files, but users
> rarely do. So to efficiently store files and make them easy to compare, we
> split the path up into two strings. Each string gets constified by being
> placed into a ConstString object that uniques the string and gives out the
> same pointer for each string it uniques so we can use pointer comparisons
> to compare two strings. FileSpec objects contain:
> >
> > class FileSpec
> > {
> > protected:
> >     //------------------------------------------------------------------
> >     // Member variables
> >     //------------------------------------------------------------------
> >     ConstString m_directory;    ///< The uniqued directory path
> >     ConstString m_filename;     ///< The uniqued filename path
> >     mutable bool m_is_resolved; ///< True if this path has been resolved.
> >     PathSyntax m_syntax;        ///< The syntax that this path uses
> (e.g. Windows / Posix)
> > };
> >
> >
> > So we can easily compare strings. You should probably step through some
> code and figure out why things are not matching up. The FileSpec class has
> some functions that try to clean up paths without calling stat:
> >
> >     void
> >     FileSpec::NormalizePath ();
> >
> >     void
> >     FileSpec::RemoveBackupDots (const ConstString &input_const_str,
> ConstString &result_const_str);
> >
> > And a few others. They might be causing the problems. You will need to
> debug this if you wish to figure out what is going wrong.
> >
> > A few tests that I ran include:
> >
> > (lldb) script
> > Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or
> Ctrl-D.
> > >>> f =
> lldb.SBFileSpec('.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m',
> False)
> > >>> print f.GetFilename()
> > EATAnimatedView.m
> > >>> print f.GetDirectory()
> >
> .//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View
> > >>> f =
> lldb.SBFileSpec('.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View/EATAnimatedView.m',
> True)
> > >>> print f.GetFilename()
> > EATAnimatedView.m
> > >>> print f.GetDirectory()
>
>
> .//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Apps/Internal/MPKEats/MPKEats/View
> >
> >
> > So we seem to split the path up correctly in both cases where we don't
> resolve and resolve the path.
> >
> >
> > >
> > > Jeffrey
> > >
> > >
> > >
> > > On Mon, Mar 7, 2016 at 11:07 AM, Greg Clayton <gclayton at apple.com>
> wrote:
> > > Not sure why we aren't treating this as a relative path. Probably
> because of the 1000 '/' characters. Feel free to dig into
> lldb_private::FileSpec and play around and see where things are going wrong.
> > >
> > > You can probably fix LLDB, when it resolves paths, to clean this up,
> but we typically don't resolve paths that we find in debug info when we run
> into it. Why? Because if you have DWARF info that contains paths that map
> to 10000 files that exist on network file system mounts, we would need to
> resolve all of those paths as we parse the line tables and calling stat()
> on all these files take a TON of time. So we won't resolve paths we find in
> debug info typically. We could try and run a path resolving function that
> doesn't call stat() to fix up an really bad paths like the ones that your
> build system is making, but we don't have support for that right now due to
> the network file system stat() issue.
> > >
> > > Greg
> > >
> > > > On Mar 5, 2016, at 11:47 AM, Jeffrey Tan <jeffrey.fudan at gmail.com>
> wrote:
> > > >
> > > > 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/20160308/4a398876/attachment-0001.html>


More information about the lldb-dev mailing list