<commit_before>Here's a short precis of how to run lldb if you are familiar with the
gdb command set:


1) LLDB Command Structure:

First some details on lldb command structure to help orient you...

Unlike gdb's command set, which is rather free-form, we tried to make
the lldb command set fairly structured.  The commands are all of the
form

<noun> <verb> [-options [option-value]] [argument [argument...]]

We also tried to reduce the number of special purpose argument
parsers, which sometimes forces the user to be a little more explicit
about stating their intentions.  The first instance you'll note of
this is the breakpoint command.  In gdb, to set a breakpoint, you
would just say:

(gdb) break set foo.c:12

or

(gdb) break set foo

if foo is a function.  As time went on, the parser that tells foo.c:12
from foo from foo.c::foo (which means the function foo in the file
foo.c) got more and more complex and bizarre, and especially in C++
there are times where there's really no way to specify the function
you want to break on.  The lldb commands are more verbose but also precise.  
So you say:

(lldb) breakpoint set -f foo.c -l 12

to set a file & line breakpoint.  To set a breakpoint on a function by name, you do:

(lldb) breakpoint set -n foo

This can allow us to be more expressive, so you can say:

(lldb) breakpoint set -M foo

to break on all methods named foo, or:

(lldb) breakpoint set -S alignLeftEdges:

to set a breakpoint on all ObjC selectors called alignLeftEdges:.  It
also makes it easy to compose specifications, like:

(lldb) breakpoint set -s foo.dylib -n foo

for all functions called foo in the shared library foo.dylib.  Suggestions
on more interesting primitives of this sort are also very welcome.

The next structural difference between lldb & gdb is that the command
line is actually parsed by the command interpreter not the commands.
That means the command syntax is more regular, but it also means you
may have to quote some arguments in lldb that you wouldn't in gdb.
But the command syntax is very simple, basically arguments, options
and option values are all white-space separated.  If you need to put a
backslash or double-quote character in an argument you back-slash it
in the argument.  So for instance:

(lldb) breakpoint set -n "-[SKTGraphicView alignLeftEdges:]"

Just like gdb, the lldb command interpreter does a shortest unique
string match on command names, so the previous command can also be
typed:

(lldb) b s -n "-[SKTGraphicView alignLeftEdges:]"

lldb also supports command completion for source file names, symbol
names, file names, etc. Completion is initiated by a hitting a <TAB>.
Individual options a command can have different completers, so for
instance the -f option in "breakpoint" completes to source files, the
-s option to currently loaded dylibs, etc...  We can even do things
like if you specify -s, and are completing on -f, we will only
list source files in the dylib specified by -s...

The individual commands are pretty extensively documented, using
with the "help" command.  And there is an "apropos" command that will
search the help for a particular word and dump a summary help string
for each matching command.

Finally, there is a mechanism to construct aliases for commonly used
commands.  So for instance if you get annoyed typing

(lldb) b s -f foo.c -l 12

you can do:

(lldb) command alias bfl breakpoint set -f %1 -l %2
(lldb) bfl foo.c 12

We have added a few aliases for commonly used commands (e.g. "step",
"next" and "continue") but we haven't tried to be exhaustive because
in our experience it is more convenient to make the basic commands
unique down to a letter or two, and then learn these sequences than
fill the namespace with lots of aliases, and then have to type them
all the way out.

However, users are free to customize lldb's command set however they
like, and since lldb reads the file ~/.lldbinit at startup, you can
store all your aliases there and they will be generally available to
you.  Your aliases are also documented in the help command so you can
remind yourself of what you've set up.

lldb also has a built-in Python interpreter, which is accessible by
the "script" command.  All the functionality of the debugger is
available as classes in the Python interpreter, so the more complex
commands that in gdb you would introduce with the "define" command can
be done by writing Python functions using the lldb-Python library,
then loading the scripts into your running session and accessing them
with the "script" command.  



2) A typical session:


a) Setting the program to debug:


As with gdb, you can start lldb and specify the file you wish to debug
on the command line:

$ lldb /Projects/Sketch/build/Debug/Sketch.app
Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64).

or you can specify it after the fact with the "file" command:

(lldb) file /Projects/Sketch/build/Debug/Sketch.app
Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64).


b) Setting breakpoints:


We've discussed how to set breakpoints above.  You can use "help break set" 
to see all the options for breakpoint setting.  For instance, we might do:

(lldb) b s -S alignLeftEdges:
Breakpoint created: 1: name = 'alignLeftEdges:', locations = 1, resolved = 1

You can find out about the breakpoints you've set with:

(lldb) break list
Current breakpoints:
1: name = 'alignLeftEdges:', locations = 1, resolved = 1
  1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Volumes/ThePlayground/Users/jingham/Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0 

Note that each "logical" breakpoint can have multiple resolved
"locations".  The logical breakpoint has an integer id, and it's
locations have a an id within their parent breakpoint (the two are
joined by a ".", e.g. 1.1 in the example above.)  Also the breakpoints
remain "live" so that if another shared library were to be loaded that
had another implementation of the "alignLeftEdges:" selector, and new
location would be added to the breakpoint 1 for it.

You can delete, disable, set conditions and ignore counts either on
all the locations generated by your logical breakpoint.  So for
instance if we wanted to add a command to print a backtrace when we
hit this breakpoint we could do:

(lldb) b command add -c 1.1
Enter your debugger command(s).  Type 'DONE' to end.
> bt
> DONE

The "-c" specifies that the breakpoint command is a set of lldb
commmand interpreter commands.  Use "-s" if you want to implement your
breakpoint command using the lldb Python interface instead.


c) Running the program:

Then you can either launch the process with the command:<commit_msg>Few clarifications.<commit_after>Here's a short precis of how to run lldb if you are familiar with the
gdb command set:


1) LLDB Command Structure:

First some details on lldb command structure to help orient you...

Unlike gdb's command set, which is rather free-form, we tried to make
the lldb command syntax fairly structured.  The commands are all of the
form

<noun> <verb> [-options [option-value]] [argument [argument...]]

The command line parsing is done before command execution, so it is
uniform across all the commands.  The command syntax is very simple,
basically arguments, options and option values are all white-space
separated.  If you need to put a backslash or double-quote character
in an argument you back-slash it in the argument.  That makes the
command syntax more regular, but it also means you may have to
quote some arguments in lldb that you wouldn't in gdb.

Options can be placed anywhere on the command line, but if the arguments
begin with a "-" then you have to tell lldb that you're done with options
using the "--" option.  So for instance, the "process launch" command takes
the "-s" option to mean "stop the process at the first instruction".  It's 
arguments are the arguments you are passing to the program.  So if you wanted
to pass an argument that contained a "-" you would have to do:

(lldb) process launch -- -program_arg value

We also tried to reduce the number of special purpose argument
parsers, which sometimes forces the user to be a little more explicit
about stating their intentions.  The first instance you'll note of
this is the breakpoint command.  In gdb, to set a breakpoint, you
would just say:

(gdb) break set foo.c:12

or

(gdb) break set foo

if foo is a function.  As time went on, the parser that tells foo.c:12
from foo from foo.c::foo (which means the function foo in the file
foo.c) got more and more complex and bizarre, and especially in C++
there are times where there's really no way to specify the function
you want to break on.  The lldb commands are more verbose but also precise.  
So you say:

(lldb) breakpoint set -f foo.c -l 12

to set a file & line breakpoint.  To set a breakpoint on a function by name, you do:

(lldb) breakpoint set -n foo

This can allow us to be more expressive, so you can say:

(lldb) breakpoint set -M foo

to break on all methods named foo, or:

(lldb) breakpoint set -S alignLeftEdges:

to set a breakpoint on all ObjC selectors called alignLeftEdges:.  It
also makes it easy to compose specifications, like:

(lldb) breakpoint set -s foo.dylib -n foo

for all functions called foo in the shared library foo.dylib.  Suggestions
on more interesting primitives of this sort are also very welcome.

So for instance:

(lldb) breakpoint set -n "-[SKTGraphicView alignLeftEdges:]"

Just like gdb, the lldb command interpreter does a shortest unique
string match on command names, so the previous command can also be
typed:

(lldb) b s -n "-[SKTGraphicView alignLeftEdges:]"

lldb also supports command completion for source file names, symbol
names, file names, etc. Completion is initiated by a hitting a <TAB>.
Individual options a command can have different completers, so for
instance the -f option in "breakpoint" completes to source files, the
-s option to currently loaded dylibs, etc...  We can even do things
like if you specify -s, and are completing on -f, we will only
list source files in the dylib specified by -s...

The individual commands are pretty extensively documented, using
with the "help" command.  And there is an "apropos" command that will
search the help for a particular word and dump a summary help string
for each matching command.

Finally, there is a mechanism to construct aliases for commonly used
commands.  So for instance if you get annoyed typing

(lldb) b s -f foo.c -l 12

you can do:

(lldb) command alias bfl breakpoint set -f %1 -l %2
(lldb) bfl foo.c 12

We have added a few aliases for commonly used commands (e.g. "step",
"next" and "continue") but we haven't tried to be exhaustive because
in our experience it is more convenient to make the basic commands
unique down to a letter or two, and then learn these sequences than
fill the namespace with lots of aliases, and then have to type them
all the way out.

However, users are free to customize lldb's command set however they
like, and since lldb reads the file ~/.lldbinit at startup, you can
store all your aliases there and they will be generally available to
you.  Your aliases are also documented in the help command so you can
remind yourself of what you've set up.

lldb also has a built-in Python interpreter, which is accessible by
the "script" command.  All the functionality of the debugger is
available as classes in the Python interpreter, so the more complex
commands that in gdb you would introduce with the "define" command can
be done by writing Python functions using the lldb-Python library,
then loading the scripts into your running session and accessing them
with the "script" command.  



2) A typical session:


a) Setting the program to debug:


As with gdb, you can start lldb and specify the file you wish to debug
on the command line:

$ lldb /Projects/Sketch/build/Debug/Sketch.app
Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64).

or you can specify it after the fact with the "file" command:

(lldb) file /Projects/Sketch/build/Debug/Sketch.app
Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64).


b) Setting breakpoints:


We've discussed how to set breakpoints above.  You can use "help break set" 
to see all the options for breakpoint setting.  For instance, we might do:

(lldb) b s -S alignLeftEdges:
Breakpoint created: 1: name = 'alignLeftEdges:', locations = 1, resolved = 1

You can find out about the breakpoints you've set with:

(lldb) break list
Current breakpoints:
1: name = 'alignLeftEdges:', locations = 1, resolved = 1
  1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Volumes/ThePlayground/Users/jingham/Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0 

Note that each "logical" breakpoint can have multiple "locations".
The logical breakpoint has an integer id, and it's locations have a an
id within their parent breakpoint (the two are joined by a ".",
e.g. 1.1 in the example above.)  

Also the breakpoints remain "live" so that if another shared library
were to be loaded that had another implementation of the
"alignLeftEdges:" selector, and new location would be added to the
breakpoint 1 for it.

The other piece of information in the breakpoint listing is whether the
breakpoint location was "resolved" or not.  A location gets resolved when
the file address it corresponds to gets loaded into the program you are
debugging.  For instance if you set a breakpoint in a dylib that then 
gets unloaded, that breakpoint location will remain, but it will no longer
be "resolved".

One other thing to note for gdb users is that lldb acts like gdb with:

(gdb) set breakpoint pending on

That is, lldb always make breakpoints from your specification, even if it
couldn't find any locations that match the specification.  You can tell whether the 
expression was resolved or not by checking the locations field in the breakpoint
reporting, and we mark the breakpoint as "pending" so you can tell you've made
a typo more easily, if that was indeed the reason no locations were found:

(lldb) b s -f no_such_file.c -l 10000000
Breakpoint created: 1: file ='no_such_file.c', line = 10000000, locations = 0 (pending)

You can delete, disable, set conditions and ignore counts either on
all the locations generated by your logical breakpoint.  So for
instance if we wanted to add a command to print a backtrace when we
hit this breakpoint we could do:

(lldb) b command add -c 1.1
Enter your debugger command(s).  Type 'DONE' to end.
> bt
> DONE

The "-c" specifies that the breakpoint command is a set of lldb
commmand interpreter commands.  Use "-s" if you want to implement your
breakpoint command using the lldb Python interface instead.


c) Running the program:

Then you can either launch the process with the command:
{'fraction_non_alphanumeric': 0.05487886494445188, 'fraction_numerical': 0.008834158747155669, 'mean_word_length': 4.135051546391753, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6315105', 'n_tokens_mistral': 4369, 'n_tokens_neox': 4158, 'n_words': 2396}