diff options
author | dim <dim@FreeBSD.org> | 2015-09-06 14:32:30 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-09-06 14:32:30 +0000 |
commit | 80b639cd40df427b9e325318efeec2d885a65f62 (patch) | |
tree | 94980f450aa3daec3e1fec217374704ad62cfe45 /source/Commands | |
parent | 8037fa4ee916fa20b3c63cbf531f4ee7e1c76138 (diff) | |
download | FreeBSD-src-80b639cd40df427b9e325318efeec2d885a65f62.zip FreeBSD-src-80b639cd40df427b9e325318efeec2d885a65f62.tar.gz |
Vendor import of (stripped) lldb trunk r242221:
https://llvm.org/svn/llvm-project/lldb/trunk@242221
Diffstat (limited to 'source/Commands')
-rw-r--r-- | source/Commands/CommandObjectBreakpoint.cpp | 34 | ||||
-rw-r--r-- | source/Commands/CommandObjectBreakpointCommand.cpp | 251 | ||||
-rw-r--r-- | source/Commands/CommandObjectCommands.cpp | 171 | ||||
-rw-r--r-- | source/Commands/CommandObjectExpression.cpp | 62 | ||||
-rw-r--r-- | source/Commands/CommandObjectPlatform.cpp | 20 | ||||
-rw-r--r-- | source/Commands/CommandObjectProcess.cpp | 47 | ||||
-rw-r--r-- | source/Commands/CommandObjectSettings.cpp | 37 | ||||
-rw-r--r-- | source/Commands/CommandObjectType.cpp | 257 | ||||
-rw-r--r-- | source/Commands/CommandObjectWatchpoint.cpp | 23 | ||||
-rw-r--r-- | source/Commands/CommandObjectWatchpointCommand.cpp | 221 |
10 files changed, 576 insertions, 547 deletions
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp index 4cbcb70..162bfb4 100644 --- a/source/Commands/CommandObjectBreakpoint.cpp +++ b/source/Commands/CommandObjectBreakpoint.cpp @@ -1249,27 +1249,27 @@ public: CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "breakpoint disable", - "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.", + "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.", NULL) { SetHelpLong( -"Disable the specified breakpoint(s) without removing it/them. \n\ -If no breakpoints are specified, disable them all.\n\ -\n\ -Note: disabling a breakpoint will cause none of its locations to be hit\n\ -regardless of whether they are enabled or disabled. So the sequence: \n\ -\n\ - (lldb) break disable 1\n\ - (lldb) break enable 1.1\n\ -\n\ -will NOT cause location 1.1 to get hit. To achieve that, do:\n\ -\n\ - (lldb) break disable 1.*\n\ - (lldb) break enable 1.1\n\ -\n\ -The first command disables all the locations of breakpoint 1, \n\ +"Disable the specified breakpoint(s) without removing them. \ +If none are specified, disable all breakpoints." R"( + +)" "Note: disabling a breakpoint will cause none of its locations to be hit \ +regardless of whether they are enabled or disabled. After the sequence:" R"( + + (lldb) break disable 1 + (lldb) break enable 1.1 + +execution will NOT stop at location 1.1. To achieve that, type: + + (lldb) break disable 1.* + (lldb) break enable 1.1 + +)" "The first command disables all the locations of breakpoint 1, \ the second re-enables the first location." - ); + ); CommandArgumentEntry arg; CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp index 180ab60..ac9c9a6 100644 --- a/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/source/Commands/CommandObjectBreakpointCommand.cpp @@ -49,143 +49,120 @@ public: m_options (interpreter) { SetHelpLong ( -"\nGeneral information about entering breakpoint commands\n\ -------------------------------------------------------\n\ -\n\ -This command will cause you to be prompted to enter the command or set of\n\ -commands you wish to be executed when the specified breakpoint is hit. You\n\ -will be told to enter your command(s), and will see a '> 'prompt. Because\n\ -you can enter one or many commands to be executed when a breakpoint is hit,\n\ -you will continue to be prompted after each new-line that you enter, until you\n\ -enter the word 'DONE', which will cause the commands you have entered to be\n\ -stored with the breakpoint and executed when the breakpoint is hit.\n\ -\n\ -Syntax checking is not necessarily done when breakpoint commands are entered.\n\ -An improperly written breakpoint command will attempt to get executed when the\n\ -breakpoint gets hit, and usually silently fail. If your breakpoint command does\n\ -not appear to be getting executed, go back and check your syntax.\n\ -\n\ -Special information about PYTHON breakpoint commands\n\ -----------------------------------------------------\n\ -\n\ -You may enter either one line of Python, multiple lines of Python (including\n\ -function definitions), or specify a Python function in a module that has already,\n\ -or will be imported. If you enter a single line of Python, that will be passed\n\ -to the Python interpreter 'as is' when the breakpoint gets hit. If you enter\n\ -function definitions, they will be passed to the Python interpreter as soon as\n\ -you finish entering the breakpoint command, and they can be called later (don't\n\ -forget to add calls to them, if you want them called when the breakpoint is\n\ -hit). If you enter multiple lines of Python that are not function definitions,\n\ -they will be collected into a new, automatically generated Python function, and\n\ -a call to the newly generated function will be attached to the breakpoint.\n\ -\n\ -\n\ -This auto-generated function is passed in three arguments:\n\ -\n\ - frame: a lldb.SBFrame object for the frame which hit breakpoint.\n\ - bp_loc: a lldb.SBBreakpointLocation object that represents the breakpoint\n\ - location that was hit.\n\ - dict: the python session dictionary hit.\n\ -\n\ -When specifying a python function with the --python-function option, you need\n\ -to supply the function name prepended by the module name. So if you import a\n\ -module named 'myutils' that contains a 'breakpoint_callback' function, you would\n\ -specify the option as:\n\ -\n\ - --python-function myutils.breakpoint_callback\n\ -\n\ -The function itself must have the following prototype:\n\ -\n\ -def breakpoint_callback(frame, bp_loc, dict):\n\ - # Your code goes here\n\ -\n\ -The arguments are the same as the 3 auto generation function arguments listed\n\ -above. Note that the global variable 'lldb.frame' will NOT be setup when this\n\ -function is called, so be sure to use the 'frame' argument. The 'frame' argument\n\ -can get you to the thread (frame.GetThread()), the thread can get you to the\n\ -process (thread.GetProcess()), and the process can get you back to the target\n\ -(process.GetTarget()).\n\ -\n\ -Important Note: Because loose Python code gets collected into functions, if you\n\ -want to access global variables in the 'loose' code, you need to specify that\n\ -they are global, using the 'global' keyword. Be sure to use correct Python\n\ -syntax, including indentation, when entering Python breakpoint commands.\n\ -\n\ -As a third option, you can pass the name of an already existing Python function\n\ -and that function will be attached to the breakpoint. It will get passed the\n\ -frame and bp_loc arguments mentioned above.\n\ -\n\ -Example Python one-line breakpoint command:\n\ -\n\ -(lldb) breakpoint command add -s python 1\n\ -Enter your Python command(s). Type 'DONE' to end.\n\ -> print \"Hit this breakpoint!\"\n\ -> DONE\n\ -\n\ -As a convenience, this also works for a short Python one-liner:\n\ -(lldb) breakpoint command add -s python 1 -o \"import time; print time.asctime()\"\n\ -(lldb) run\n\ -Launching '.../a.out' (x86_64)\n\ -(lldb) Fri Sep 10 12:17:45 2010\n\ -Process 21778 Stopped\n\ -* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread\n\ - 36 \n\ - 37 int c(int val)\n\ - 38 {\n\ - 39 -> return val + 3;\n\ - 40 }\n\ - 41 \n\ - 42 int main (int argc, char const *argv[])\n\ -(lldb)\n\ -\n\ -Example multiple line Python breakpoint command, using function definition:\n\ -\n\ -(lldb) breakpoint command add -s python 1\n\ -Enter your Python command(s). Type 'DONE' to end.\n\ -> def breakpoint_output (bp_no):\n\ -> out_string = \"Hit breakpoint number \" + repr (bp_no)\n\ -> print out_string\n\ -> return True\n\ -> breakpoint_output (1)\n\ -> DONE\n\ -\n\ -\n\ -Example multiple line Python breakpoint command, using 'loose' Python:\n\ -\n\ -(lldb) breakpoint command add -s p 1\n\ -Enter your Python command(s). Type 'DONE' to end.\n\ -> global bp_count\n\ -> bp_count = bp_count + 1\n\ -> print \"Hit this breakpoint \" + repr(bp_count) + \" times!\"\n\ -> DONE\n\ -\n\ -In this case, since there is a reference to a global variable,\n\ -'bp_count', you will also need to make sure 'bp_count' exists and is\n\ -initialized:\n\ -\n\ -(lldb) script\n\ ->>> bp_count = 0\n\ ->>> quit()\n\ -\n\ -(lldb)\n\ -\n\ -\n\ -Your Python code, however organized, can optionally return a value.\n\ -If the returned value is False, that tells LLDB not to stop at the breakpoint\n\ -to which the code is associated. Returning anything other than False, or even\n\ -returning None, or even omitting a return statement entirely, will cause\n\ -LLDB to stop.\n\ -\n\ -Final Note: If you get a warning that no breakpoint command was generated, but\n\ -you did not get any syntax errors, you probably forgot to add a call to your\n\ -functions.\n\ -\n\ -Special information about debugger command breakpoint commands\n\ ---------------------------------------------------------------\n\ -\n\ -You may enter any debugger command, exactly as you would at the debugger prompt.\n\ -You may enter as many debugger commands as you like, but do NOT enter more than\n\ -one command per line.\n" ); +R"( +General information about entering breakpoint commands +------------------------------------------------------ + +)" "This command will prompt for commands to be executed when the specified \ +breakpoint is hit. Each command is typed on its own line following the '> ' \ +prompt until 'DONE' is entered." R"( + +)" "Syntactic errors may not be detected when initially entered, and many \ +malformed commands can silently fail when executed. If your breakpoint commands \ +do not appear to be executing, double-check the command syntax." R"( + +)" "Note: You may enter any debugger command exactly as you would at the debugger \ +prompt. There is no limit to the number of commands supplied, but do NOT enter \ +more than one command per line." R"( + +Special information about PYTHON breakpoint commands +---------------------------------------------------- + +)" "You may enter either one or more lines of Python, including function \ +definitions or calls to functions that will have been imported by the time \ +the code executes. Single line breakpoint commands will be interpreted 'as is' \ +when the breakpoint is hit. Multiple lines of Python will be wrapped in a \ +generated function, and a call to the function will be attached to the breakpoint." R"( + +This auto-generated function is passed in three arguments: + + frame: an lldb.SBFrame object for the frame which hit breakpoint. + + bp_loc: an lldb.SBBreakpointLocation object that represents the breakpoint location that was hit. + + dict: the python session dictionary hit. + +)" "When specifying a python function with the --python-function option, you need \ +to supply the function name prepended by the module name:" R"( + + --python-function myutils.breakpoint_callback + +The function itself must have the following prototype: + +def breakpoint_callback(frame, bp_loc, dict): + # Your code goes here + +)" "The arguments are the same as the arguments passed to generated functions as \ +described above. Note that the global variable 'lldb.frame' will NOT be updated when \ +this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ +can get you to the thread via frame.GetThread(), the thread can get you to the \ +process via thread.GetProcess(), and the process can get you back to the target \ +via process.GetTarget()." R"( + +)" "Important Note: As Python code gets collected into functions, access to global \ +variables requires explicit scoping using the 'global' keyword. Be sure to use correct \ +Python syntax, including indentation, when entering Python breakpoint commands." R"( + +Example Python one-line breakpoint command: + +(lldb) breakpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> print "Hit this breakpoint!" +> DONE + +As a convenience, this also works for a short Python one-liner: + +(lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()' +(lldb) run +Launching '.../a.out' (x86_64) +(lldb) Fri Sep 10 12:17:45 2010 +Process 21778 Stopped +* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread + 36 + 37 int c(int val) + 38 { + 39 -> return val + 3; + 40 } + 41 + 42 int main (int argc, char const *argv[]) + +Example multiple line Python breakpoint command: + +(lldb) breakpoint command add -s p 1 +Enter your Python command(s). Type 'DONE' to end. +> global bp_count +> bp_count = bp_count + 1 +> print "Hit this breakpoint " + repr(bp_count) + " times!" +> DONE + +Example multiple line Python breakpoint command, using function definition: + +(lldb) breakpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> def breakpoint_output (bp_no): +> out_string = "Hit breakpoint number " + repr (bp_no) +> print out_string +> return True +> breakpoint_output (1) +> DONE + +)" "In this case, since there is a reference to a global variable, \ +'bp_count', you will also need to make sure 'bp_count' exists and is \ +initialized:" R"( + +(lldb) script +>>> bp_count = 0 +>>> quit() + +)" "Your Python code, however organized, can optionally return a value. \ +If the returned value is False, that tells LLDB not to stop at the breakpoint \ +to which the code is associated. Returning anything other than False, or even \ +returning None, or even omitting a return statement entirely, will cause \ +LLDB to stop." R"( + +)" "Final Note: A warning that no breakpoint command was generated when there \ +are no syntax errors may indicate that a function was declared but never called." + ); CommandArgumentEntry arg; CommandArgumentData bp_id_arg; diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index 5fd99cf..f56d089 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -450,60 +450,74 @@ public: NULL) { SetHelpLong( - "'alias' allows the user to create a short-cut or abbreviation for long \n\ - commands, multi-word commands, and commands that take particular options. \n\ - Below are some simple examples of how one might use the 'alias' command: \n\ - \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ - // command. \n\ - 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ - // command. Since breakpoint commands are two-word \n\ - // commands, the user will still need to enter the \n\ - // second word after 'bp', e.g. 'bp enable' or \n\ - // 'bp delete'. \n\ - 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\ - // two-word command 'breakpoint list'. \n\ - \nAn alias can include some options for the command, with the values either \n\ - filled in at the time the alias is created, or specified as positional \n\ - arguments, to be filled in when the alias is invoked. The following example \n\ - shows how to create aliases with options: \n\ - \n\ - 'command alias bfl breakpoint set -f %1 -l %2' \n\ - \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ - options already part of the alias. So if the user wants to set a breakpoint \n\ - by file and line without explicitly having to use the -f and -l options, the \n\ - user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\ - for the actual arguments that will be passed when the alias command is used. \n\ - The number in the placeholder refers to the position/order the actual value \n\ - occupies when the alias is used. All the occurrences of '%1' in the alias \n\ - will be replaced with the first argument, all the occurrences of '%2' in the \n\ - alias will be replaced with the second argument, and so on. This also allows \n\ - actual arguments to be used multiple times within an alias (see 'process \n\ - launch' example below). \n\ - Note: the positional arguments must substitute as whole words in the resultant\n\ - command, so you can't at present do something like:\n\ - \n\ - command alias bcppfl breakpoint set -f %1.cpp -l %2\n\ - \n\ - to get the file extension \".cpp\" automatically appended. For more complex\n\ - aliasing, use the \"command regex\" command instead.\n\ - \nSo in the 'bfl' case, the actual file value will be \n\ - filled in with the first argument following 'bfl' and the actual line number \n\ - value will be filled in with the second argument. The user would use this \n\ - alias as follows: \n\ - \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\ - <... some time later ...> \n\ - (lldb) bfl my-file.c 137 \n\ - \nThis would be the same as if the user had entered \n\ - 'breakpoint set -f my-file.c -l 137'. \n\ - \nAnother example: \n\ - \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\ - (lldb) pltty /dev/tty0 \n\ - // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ - \nIf the user always wanted to pass the same value to a particular option, the \n\ - alias could be defined with that value directly in the alias as a constant, \n\ - rather than using a positional placeholder: \n\ - \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ - // 3 of whatever file is indicated. \n"); +"'alias' allows the user to create a short-cut or abbreviation for long \ +commands, multi-word commands, and commands that take particular options. \ +Below are some simple examples of how one might use the 'alias' command:" R"( + +(lldb) command alias sc script + + Creates the abbreviation 'sc' for the 'script' command. + +(lldb) command alias bp breakpoint + +)" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \ +breakpoint commands are two-word commands, the user would still need to \ +enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"( + +(lldb) command alias bpl breakpoint list + + Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'. + +)" "An alias can include some options for the command, with the values either \ +filled in at the time the alias is created, or specified as positional \ +arguments, to be filled in when the alias is invoked. The following example \ +shows how to create aliases with options:" R"( + +(lldb) command alias bfl breakpoint set -f %1 -l %2 + +)" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \ +options already part of the alias. So if the user wants to set a breakpoint \ +by file and line without explicitly having to use the -f and -l options, the \ +user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \ +for the actual arguments that will be passed when the alias command is used. \ +The number in the placeholder refers to the position/order the actual value \ +occupies when the alias is used. All the occurrences of '%1' in the alias \ +will be replaced with the first argument, all the occurrences of '%2' in the \ +alias will be replaced with the second argument, and so on. This also allows \ +actual arguments to be used multiple times within an alias (see 'process \ +launch' example below)." R"( + +)" "Note: the positional arguments must substitute as whole words in the resultant \ +command, so you can't at present do something like this to append the file extension \ +\".cpp\":" R"( + +(lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2 + +)" "For more complex aliasing, use the \"command regex\" command instead. In the \ +'bfl' case above, the actual file value will be filled in with the first argument \ +following 'bfl' and the actual line number value will be filled in with the second \ +argument. The user would use this alias as follows:" R"( + +(lldb) command alias bfl breakpoint set -f %1 -l %2 +(lldb) bfl my-file.c 137 + +This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'. + +Another example: + +(lldb) command alias pltty process launch -s -o %1 -e %1 +(lldb) pltty /dev/tty0 + + Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0' + +)" "If the user always wanted to pass the same value to a particular option, the \ +alias could be defined with that value directly in the alias as a constant, \ +rather than using a positional placeholder:" R"( + +(lldb) command alias bl3 breakpoint set -f %1 -l 3 + + Always sets a breakpoint on line 3 of whatever file is indicated.)" + ); CommandArgumentEntry arg1; CommandArgumentEntry arg2; @@ -960,31 +974,30 @@ public: IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand), m_options (interpreter) { - SetHelpLong( -"This command allows the user to create powerful regular expression commands\n" -"with substitutions. The regular expressions and substitutions are specified\n" -"using the regular expression substitution format of:\n" -"\n" -" s/<regex>/<subst>/\n" -"\n" -"<regex> is a regular expression that can use parenthesis to capture regular\n" -"expression input and substitute the captured matches in the output using %1\n" -"for the first match, %2 for the second, and so on.\n" -"\n" -"The regular expressions can all be specified on the command line if more than\n" -"one argument is provided. If just the command name is provided on the command\n" -"line, then the regular expressions and substitutions can be entered on separate\n" -" lines, followed by an empty line to terminate the command definition.\n" -"\n" -"EXAMPLES\n" -"\n" -"The following example will define a regular expression command named 'f' that\n" -"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n" -"a number follows 'f':\n" -"\n" -" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" -"\n" - ); + SetHelpLong(R"( +)" "This command allows the user to create powerful regular expression commands \ +with substitutions. The regular expressions and substitutions are specified \ +using the regular expression substitution format of:" R"( + + s/<regex>/<subst>/ + +)" "<regex> is a regular expression that can use parenthesis to capture regular \ +expression input and substitute the captured matches in the output using %1 \ +for the first match, %2 for the second, and so on." R"( + +)" "The regular expressions can all be specified on the command line if more than \ +one argument is provided. If just the command name is provided on the command \ +line, then the regular expressions and substitutions can be entered on separate \ +lines, followed by an empty line to terminate the command definition." R"( + +EXAMPLES + +)" "The following example will define a regular expression command named 'f' that \ +will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \ +a number follows 'f':" R"( + + (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')" + ); } ~CommandObjectCommandsAddRegex() diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp index f4bb8fb..1be17a0 100644 --- a/source/Commands/CommandObjectExpression.cpp +++ b/source/Commands/CommandObjectExpression.cpp @@ -202,35 +202,39 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete m_expr_line_count (0), m_expr_lines () { - SetHelpLong( -"Timeouts:\n\ - If the expression can be evaluated statically (without running code) then it will be.\n\ - Otherwise, by default the expression will run on the current thread with a short timeout:\n\ - currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\ - and resumed with all threads running. You can use the -a option to disable retrying on all\n\ - threads. You can use the -t option to set a shorter timeout.\n\ -\n\ -User defined variables:\n\ - You can define your own variables for convenience or to be used in subsequent expressions.\n\ - You define them the same way you would define variables in C. If the first character of \n\ - your user defined variable is a $, then the variable's value will be available in future\n\ - expressions, otherwise it will just be available in the current expression.\n\ -\n\ -\n\ -Continuing evaluation after a breakpoint:\n\ - If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once\n\ - you are done with your investigation, you can either remove the expression execution frames\n\ - from the stack with \"thread return -x\" or if you are still interested in the expression result\n\ - you can issue the \"continue\" command and the expression evaluation will complete and the\n\ - expression result will be available using the \"thread.completed-expression\" key in the thread\n\ - format.\n\ -\n\ -Examples: \n\ -\n\ - expr my_struct->a = my_array[3] \n\ - expr -f bin -- (index * 8) + 5 \n\ - expr unsigned int $foo = 5\n\ - expr char c[] = \"foo\"; c[0]\n"); + SetHelpLong( +R"( +Timeouts: + +)" " If the expression can be evaluated statically (without running code) then it will be. \ +Otherwise, by default the expression will run on the current thread with a short timeout: \ +currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \ +and resumed with all threads running. You can use the -a option to disable retrying on all \ +threads. You can use the -t option to set a shorter timeout." R"( + +User defined variables: + +)" " You can define your own variables for convenience or to be used in subsequent expressions. \ +You define them the same way you would define variables in C. If the first character of \ +your user defined variable is a $, then the variable's value will be available in future \ +expressions, otherwise it will just be available in the current expression." R"( + +Continuing evaluation after a breakpoint: + +)" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \ +you are done with your investigation, you can either remove the expression execution frames \ +from the stack with \"thread return -x\" or if you are still interested in the expression result \ +you can issue the \"continue\" command and the expression evaluation will complete and the \ +expression result will be available using the \"thread.completed-expression\" key in the thread \ +format." R"( + +Examples: + + expr my_struct->a = my_array[3] + expr -f bin -- (index * 8) + 5 + expr unsigned int $foo = 5 + expr char c[] = \"foo\"; c[0])" + ); CommandArgumentEntry arg; CommandArgumentData expression_arg; diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index 866587f..a0979d0 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -1067,10 +1067,12 @@ public: 0) { SetHelpLong( -"Examples: \n\ -\n\ - platform get-file /the/remote/file/path /the/local/file/path\n\ - # Transfer a file from the remote end with file path /the/remote/file/path to the local host.\n"); +R"(Examples: + +(lldb) platform get-file /the/remote/file/path /the/local/file/path + + Transfer a file from the remote end with file path /the/remote/file/path to the local host.)" + ); CommandArgumentEntry arg1, arg2; CommandArgumentData file_arg_remote, file_arg_host; @@ -1150,10 +1152,12 @@ public: 0) { SetHelpLong( -"Examples: \n\ -\n\ - platform get-size /the/remote/file/path\n\ - # Get the file size from the remote end with path /the/remote/file/path.\n"); +R"(Examples: + +(lldb) platform get-size /the/remote/file/path + + Get the file size from the remote end with path /the/remote/file/path.)" + ); CommandArgumentEntry arg1; CommandArgumentData file_arg_remote; diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index 4414bdf..e587ead 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -1337,7 +1337,7 @@ protected: if (::isxdigit (signal_name[0])) signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); else - signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); + signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); if (signo == LLDB_INVALID_SIGNAL_NUMBER) { @@ -1681,7 +1681,8 @@ public: NULL), m_options (interpreter) { - SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); + SetHelpLong ("\nIf no signals are specified, update them all. If no update " + "option is specified, list the current values."); CommandArgumentEntry arg; CommandArgumentData signal_arg; @@ -1734,14 +1735,14 @@ public: } void - PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) + PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp) { bool stop; bool suppress; bool notify; str.Printf ("%-11s ", sig_name); - if (signals.GetSignalInfo (signo, suppress, stop, notify)) + if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) { bool pass = !suppress; str.Printf ("%s %s %s", @@ -1753,7 +1754,7 @@ public: } void - PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) + PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp) { PrintSignalHeader (str); @@ -1762,18 +1763,18 @@ public: size_t num_args = signal_args.GetArgumentCount(); for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) - PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); + PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp); } } else // Print info for ALL signals { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { - PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); - signo = signals.GetNextSignalNumber (signo); + PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp); + signo = signals_sp->GetNextSignalNumber(signo); } } } @@ -1830,27 +1831,27 @@ protected: } size_t num_args = signal_args.GetArgumentCount(); - UnixSignals &signals = process_sp->GetUnixSignals(); + UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); int num_signals_set = 0; if (num_args > 0) { for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) { // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees // the value is either 0 or 1. if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); ++num_signals_set; } else @@ -1866,25 +1867,25 @@ protected: { if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } - signo = signals.GetNextSignalNumber (signo); + signo = signals_sp->GetNextSignalNumber(signo); } } } } - PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); + PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp); if (num_signals_set > 0) result.SetStatus (eReturnStatusSuccessFinishNoResult); diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp index ccbf98c..8ed783b 100644 --- a/source/Commands/CommandObjectSettings.cpp +++ b/source/Commands/CommandObjectSettings.cpp @@ -60,24 +60,25 @@ public: m_arguments.push_back (arg2); SetHelpLong ( -"When setting a dictionary or array variable, you can set multiple entries \n\ -at once by giving the values to the set command. For example: \n\ -\n\ -(lldb) settings set target.run-args value1 value2 value3 \n\ -(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345 \n\ -\n\ -(lldb) settings show target.run-args \n\ - [0]: 'value1' \n\ - [1]: 'value2' \n\ - [3]: 'value3' \n\ -(lldb) settings show target.env-vars \n\ - 'MYPATH=~/.:/usr/bin'\n\ - 'SOME_ENV_VAR=12345' \n\ -\n\ -Warning: The 'set' command re-sets the entire array or dictionary. If you \n\ -just want to add, remove or update individual values (or add something to \n\ -the end), use one of the other settings sub-commands: append, replace, \n\ -insert-before or insert-after.\n"); +"\nWhen setting a dictionary or array variable, you can set multiple entries \ +at once by giving the values to the set command. For example:" R"( + +(lldb) settings set target.run-args value1 value2 value3 +(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345 + +(lldb) settings show target.run-args + [0]: 'value1' + [1]: 'value2' + [3]: 'value3' +(lldb) settings show target.env-vars + 'MYPATH=~/.:/usr/bin' + 'SOME_ENV_VAR=12345' + +)" "Warning: The 'set' command re-sets the entire array or dictionary. If you \ +just want to add, remove or update individual values (or add something to \ +the end), use one of the other settings sub-commands: append, replace, \ +insert-before or insert-after." + ); } diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp index 7c8061a..584e94d 100644 --- a/source/Commands/CommandObjectType.cpp +++ b/source/Commands/CommandObjectType.cpp @@ -764,31 +764,39 @@ public: m_arguments.push_back (type_arg); SetHelpLong( - "Some examples of using this command.\n" - "We use as reference the following snippet of code:\n" - "\n" - "typedef int Aint;\n" - "typedef float Afloat;\n" - "typedef Aint Bint;\n" - "typedef Afloat Bfloat;\n" - "\n" - "Aint ix = 5;\n" - "Bint iy = 5;\n" - "\n" - "Afloat fx = 3.14;\n" - "BFloat fy = 3.14;\n" - "\n" - "Typing:\n" - "type format add -f hex AInt\n" - "frame variable iy\n" - "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n" - "To prevent this type\n" - "type format add -f hex -C no AInt\n" - "\n" - "A similar reasoning applies to\n" - "type format add -f hex -C no float -p\n" - "which now prints all floats and float&s as hexadecimal, but does not format float*s\n" - "and does not change the default display for Afloat and Bfloat objects.\n" +R"( +The following examples of 'type format add' refer to this code snippet for context: + + typedef int Aint; + typedef float Afloat; + typedef Aint Bint; + typedef Afloat Bfloat; + + Aint ix = 5; + Bint iy = 5; + + Afloat fx = 3.14; + BFloat fy = 3.14; + +Adding default formatting: + +(lldb) type format add -f hex AInt +(lldb) frame variable iy + +)" " Produces hexidecimal display of iy, because no formatter is available for Bint and \ +the one for Aint is used instead." R"( + +To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains: + + +(lldb) type format add -f hex -C no AInt + +Similar reasoning applies to this: + +(lldb) type format add -f hex -C no float -p + +)" " All float values and float references are now formatted as hexadecimal, but not \ +pointers to floats. Nor will it change the default display for Afloat and Bfloat objects." ); // Add the "--format" to all options groups @@ -1736,69 +1744,86 @@ CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &in m_arguments.push_back (type_arg); SetHelpLong( - "Some examples of using this command.\n" - "We use as reference the following snippet of code:\n" - "struct JustADemo\n" - "{\n" - "int* ptr;\n" - "float value;\n" - "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n" - "};\n" - "JustADemo object(42,3.14);\n" - "struct AnotherDemo : public JustADemo\n" - "{\n" - "uint8_t byte;\n" - "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n" - "};\n" - "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n" - "\n" - "type summary add --summary-string \"the answer is ${*var.ptr}\" JustADemo\n" - "when typing frame variable object you will get \"the answer is 42\"\n" - "type summary add --summary-string \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n" - "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n" - "\n" - "Alternatively, you could also say\n" - "type summary add --summary-string \"${var%V} -> ${*var}\" \"int *\"\n" - "and replace the above summary string with\n" - "type summary add --summary-string \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n" - "to obtain a similar result\n" - "\n" - "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n" - "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n" - "\n" - "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n" - "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n" - "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n" - "A similar option -r exists for references.\n" - "\n" - "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n" - "you can use the -c option, without giving any summary string:\n" - "type summary add -c JustADemo\n" - "frame variable object\n" - "the output being similar to (ptr=0xsomeaddress, value=3.14)\n" - "\n" - "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n" - "type summary add -e --summary-string \"*ptr = ${*var.ptr}\" JustADemo\n" - "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n" - "to get an output like:\n" - "\n" - "*ptr = 42 {\n" - " ptr = 0xsomeaddress\n" - " value = 3.14\n" - "}\n" - "\n" - "You can also add Python summaries, in which case you will use lldb public API to gather information from your variables" - "and elaborate them to a meaningful summary inside a script written in Python. The variable object will be passed to your" - "script as an SBValue object. The following example might help you when starting to use the Python summaries feature:\n" - "type summary add JustADemo -o \"value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();\"\n" - "If you prefer to type your scripts on multiple lines, you will use the -P option and then type your script, ending it with " - "the word DONE on a line by itself to mark you're finished editing your code:\n" - "(lldb)type summary add JustADemo -P\n" - " value = valobj.GetChildMemberWithName('value');\n" - " return 'My value is ' + value.GetValue();\n" - "DONE\n" - "(lldb) <-- type further LLDB commands here\n" - ); +R"( +The following examples of 'type summary add' refer to this code snippet for context: + + struct JustADemo + { + int* ptr; + float value; + JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {} + }; + JustADemo demo_instance(42, 3.14); + + typedef JustADemo NewDemo; + NewDemo new_demo_instance(42, 3.14); + +(lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo + + Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42" + +(lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo + + Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14" + +)" "Alternatively, you could define formatting for all pointers to integers and \ +rely on that when formatting JustADemo to obtain the same result:" R"( + +(lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *" +(lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo + +)" "Type summaries are automatically applied to derived typedefs, so the examples \ +above apply to both JustADemo and NewDemo. The cascade option can be used to \ +suppress this behavior:" R"( + +(lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no + + The summary will now be used for values of JustADemo but not NewDemo. + +)" "By default summaries are shown for pointers and references to values of the \ +specified type. To suppress formatting for pointers use the -p option, or apply \ +the corresponding -r option to suppress formatting for references:" R"( + +(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo + +)" "One-line summaries including all fields in a type can be inferred without supplying an \ +explicit summary string by passing the -c option:" R"( + +(lldb) type summary add -c JustADemo +(lldb) frame variable demo_instance +(ptr=<address>, value=3.14) + +)" "Type summaries normally suppress the nested display of individual fields. To \ +supply a summary to supplement the default structure add the -e option:" R"( + +(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo + +)" "Now when displaying JustADemo values the int* is displayed, followed by the \ +standard LLDB sequence of children, one per line:" R"( + +*ptr = 42 { + ptr = <address> + value = 3.14 +} + +)" "You can also add summaries written in Python. These scripts use lldb public API to \ +gather information from your variables and produce a meaningful summary. To start a \ +multi-line script use the -P option. The function declaration will be displayed along with \ +a comment describing the two arguments. End your script with the word 'DONE' on a line by \ +itself:" R"( + +(lldb) type summary add JustADemo -P +def function (valobj,internal_dict): +"""valobj: an SBValue which you want to provide a summary for +internal_dict: an LLDB support object not to be used""" + value = valobj.GetChildMemberWithName('value'); + return 'My value is ' + value.GetValue(); + DONE + +Alternatively, the -o option can be used when providing a simple one-line Python script: + +(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")" + ); } bool @@ -4117,31 +4142,37 @@ public: m_arguments.push_back (type_arg); SetHelpLong( - "Some examples of using this command.\n" - "We use as reference the following snippet of code:\n" - "\n" - "class Foo {;\n" - " int a;\n" - " int b;\n" - " int c;\n" - " int d;\n" - " int e;\n" - " int f;\n" - " int g;\n" - " int h;\n" - " int i;\n" - "} \n" - "Typing:\n" - "type filter add --child a --child g Foo\n" - "frame variable a_foo\n" - "will produce an output where only a and g are displayed\n" - "Other children of a_foo (b,c,d,e,f,h and i) are available by asking for them, as in:\n" - "frame variable a_foo.b a_foo.c ... a_foo.i\n" - "\n" - "Use option --raw to frame variable prevails on the filter\n" - "frame variable a_foo --raw\n" - "shows all the children of a_foo (a thru i) as if no filter was defined\n" - ); +R"( +The following examples of 'type filter add' refer to this code snippet for context: + + class Foo { + int a; + int b; + int c; + int d; + int e; + int f; + int g; + int h; + int i; + } + Foo my_foo; + +Adding a simple filter: + +(lldb) type filter add --child a --child g Foo +(lldb) frame variable my_foo + +)" "Produces output where only a and g are displayed. Other children of my_foo \ +(b, c, d, e, f, h and i) are available by asking for them explicitly:" R"( + +(lldb) frame variable my_foo.b my_foo.c my_foo.i + +)" "The formatting option --raw on frame variable bypasses the filter, showing \ +all children of my_foo as if no filter was defined:" R"( + +(lldb) frame variable my_foo --raw)" + ); } ~CommandObjectTypeFilterAdd () diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp index 650fd25..414e784 100644 --- a/source/Commands/CommandObjectWatchpoint.cpp +++ b/source/Commands/CommandObjectWatchpoint.cpp @@ -931,10 +931,14 @@ public: m_option_watchpoint () { SetHelpLong( - "Examples: \n\ - \n\ - watchpoint set variable -w read_write my_global_var \n\ - # Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n"); +R"( +Examples: + +(lldb) watchpoint set variable -w read_write my_global_var + +)" " Watches my_global_var for read/write access, with the region to watch \ +corresponding to the byte size of the data type." + ); CommandArgumentEntry arg; CommandArgumentData var_name_arg; @@ -1138,10 +1142,13 @@ public: m_option_watchpoint () { SetHelpLong( - "Examples: \n\ - \n\ - watchpoint set expression -w write -x 1 -- foo + 32\n\ - # Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n"); +R"( +Examples: + +(lldb) watchpoint set expression -w write -x 1 -- foo + 32 + + Watches write access for the 1-byte region pointed to by the address 'foo + 32')" + ); CommandArgumentEntry arg; CommandArgumentData expression_arg; diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp index d7d064e..84342cc 100644 --- a/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/source/Commands/CommandObjectWatchpointCommand.cpp @@ -48,121 +48,112 @@ public: m_options (interpreter) { SetHelpLong ( -"\nGeneral information about entering watchpoint commands \n\ ------------------------------------------------------- \n\ - \n\ -This command will cause you to be prompted to enter the command or set \n\ -of commands you wish to be executed when the specified watchpoint is \n\ -hit. You will be told to enter your command(s), and will see a '> ' \n\ -prompt. Because you can enter one or many commands to be executed when \n\ -a watchpoint is hit, you will continue to be prompted after each \n\ -new-line that you enter, until you enter the word 'DONE', which will \n\ -cause the commands you have entered to be stored with the watchpoint \n\ -and executed when the watchpoint is hit. \n\ - \n\ -Syntax checking is not necessarily done when watchpoint commands are \n\ -entered. An improperly written watchpoint command will attempt to get \n\ -executed when the watchpoint gets hit, and usually silently fail. If \n\ -your watchpoint command does not appear to be getting executed, go \n\ -back and check your syntax. \n\ - \n\ - \n\ -Special information about PYTHON watchpoint commands \n\ ----------------------------------------------------- \n\ - \n\ -You may enter either one line of Python or multiple lines of Python \n\ -(including defining whole functions, if desired). If you enter a \n\ -single line of Python, that will be passed to the Python interpreter \n\ -'as is' when the watchpoint gets hit. If you enter function \n\ -definitions, they will be passed to the Python interpreter as soon as \n\ -you finish entering the watchpoint command, and they can be called \n\ -later (don't forget to add calls to them, if you want them called when \n\ -the watchpoint is hit). If you enter multiple lines of Python that \n\ -are not function definitions, they will be collected into a new, \n\ -automatically generated Python function, and a call to the newly \n\ -generated function will be attached to the watchpoint. \n\ - \n\ -This auto-generated function is passed in two arguments: \n\ - \n\ - frame: an SBFrame object representing the frame which hit the watchpoint. \n\ - From the frame you can get back to the thread and process. \n\ - wp: the watchpoint that was hit. \n\ - \n\ -Important Note: Because loose Python code gets collected into functions, \n\ -if you want to access global variables in the 'loose' code, you need to \n\ -specify that they are global, using the 'global' keyword. Be sure to \n\ -use correct Python syntax, including indentation, when entering Python \n\ -watchpoint commands. \n\ - \n\ -As a third option, you can pass the name of an already existing Python function \n\ -and that function will be attached to the watchpoint. It will get passed the \n\ -frame and wp_loc arguments mentioned above. \n\ - \n\ -Example Python one-line watchpoint command: \n\ - \n\ -(lldb) watchpoint command add -s python 1 \n\ -Enter your Python command(s). Type 'DONE' to end. \n\ -> print \"Hit this watchpoint!\" \n\ -> DONE \n\ - \n\ -As a convenience, this also works for a short Python one-liner: \n\ -(lldb) watchpoint command add -s python 1 -o \"import time; print time.asctime()\" \n\ -(lldb) run \n\ -Launching '.../a.out' (x86_64) \n\ -(lldb) Fri Sep 10 12:17:45 2010 \n\ -Process 21778 Stopped \n\ -* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = watchpoint 1.1, queue = com.apple.main-thread \n\ - 36 \n\ - 37 int c(int val)\n\ - 38 {\n\ - 39 -> return val + 3;\n\ - 40 }\n\ - 41 \n\ - 42 int main (int argc, char const *argv[])\n\ -(lldb) \n\ - \n\ -Example multiple line Python watchpoint command, using function definition: \n\ - \n\ -(lldb) watchpoint command add -s python 1 \n\ -Enter your Python command(s). Type 'DONE' to end. \n\ -> def watchpoint_output (wp_no): \n\ -> out_string = \"Hit watchpoint number \" + repr (wp_no) \n\ -> print out_string \n\ -> return True \n\ -> watchpoint_output (1) \n\ -> DONE \n\ - \n\ - \n\ -Example multiple line Python watchpoint command, using 'loose' Python: \n\ - \n\ -(lldb) watchpoint command add -s p 1 \n\ -Enter your Python command(s). Type 'DONE' to end. \n\ -> global wp_count \n\ -> wp_count = wp_count + 1 \n\ -> print \"Hit this watchpoint \" + repr(wp_count) + \" times!\" \n\ -> DONE \n\ - \n\ -In this case, since there is a reference to a global variable, \n\ -'wp_count', you will also need to make sure 'wp_count' exists and is \n\ -initialized: \n\ - \n\ -(lldb) script \n\ ->>> wp_count = 0 \n\ ->>> quit() \n\ - \n\ -(lldb) \n\ - \n\ - \n\ -Final Note: If you get a warning that no watchpoint command was generated, \n\ -but you did not get any syntax errors, you probably forgot to add a call \n\ -to your functions. \n\ - \n\ -Special information about debugger command watchpoint commands \n\ --------------------------------------------------------------- \n\ - \n\ -You may enter any debugger command, exactly as you would at the \n\ -debugger prompt. You may enter as many debugger commands as you like, \n\ -but do NOT enter more than one command per line. \n" ); +R"( +General information about entering watchpoint commands +------------------------------------------------------ + +)" "This command will prompt for commands to be executed when the specified \ +watchpoint is hit. Each command is typed on its own line following the '> ' \ +prompt until 'DONE' is entered." R"( + +)" "Syntactic errors may not be detected when initially entered, and many \ +malformed commands can silently fail when executed. If your watchpoint commands \ +do not appear to be executing, double-check the command syntax." R"( + +)" "Note: You may enter any debugger command exactly as you would at the debugger \ +prompt. There is no limit to the number of commands supplied, but do NOT enter \ +more than one command per line." R"( + +Special information about PYTHON watchpoint commands +---------------------------------------------------- + +)" "You may enter either one or more lines of Python, including function \ +definitions or calls to functions that will have been imported by the time \ +the code executes. Single line watchpoint commands will be interpreted 'as is' \ +when the watchpoint is hit. Multiple lines of Python will be wrapped in a \ +generated function, and a call to the function will be attached to the watchpoint." R"( + +This auto-generated function is passed in three arguments: + + frame: an lldb.SBFrame object for the frame which hit the watchpoint. + + wp: the watchpoint that was hit. + +)" "When specifying a python function with the --python-function option, you need \ +to supply the function name prepended by the module name:" R"( + + --python-function myutils.watchpoint_callback + +The function itself must have the following prototype: + +def watchpoint_callback(frame, wp): + # Your code goes here + +)" "The arguments are the same as the arguments passed to generated functions as \ +described above. Note that the global variable 'lldb.frame' will NOT be updated when \ +this function is called, so be sure to use the 'frame' argument. The 'frame' argument \ +can get you to the thread via frame.GetThread(), the thread can get you to the \ +process via thread.GetProcess(), and the process can get you back to the target \ +via process.GetTarget()." R"( + +)" "Important Note: As Python code gets collected into functions, access to global \ +variables requires explicit scoping using the 'global' keyword. Be sure to use correct \ +Python syntax, including indentation, when entering Python watchpoint commands." R"( + +Example Python one-line watchpoint command: + +(lldb) watchpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> print "Hit this watchpoint!" +> DONE + +As a convenience, this also works for a short Python one-liner: + +(lldb) watchpoint command add -s python 1 -o 'import time; print time.asctime()' +(lldb) run +Launching '.../a.out' (x86_64) +(lldb) Fri Sep 10 12:17:45 2010 +Process 21778 Stopped +* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = watchpoint 1.1, queue = com.apple.main-thread + 36 + 37 int c(int val) + 38 { + 39 -> return val + 3; + 40 } + 41 + 42 int main (int argc, char const *argv[]) + +Example multiple line Python watchpoint command, using function definition: + +(lldb) watchpoint command add -s python 1 +Enter your Python command(s). Type 'DONE' to end. +> def watchpoint_output (wp_no): +> out_string = "Hit watchpoint number " + repr (wp_no) +> print out_string +> return True +> watchpoint_output (1) +> DONE + +Example multiple line Python watchpoint command, using 'loose' Python: + +(lldb) watchpoint command add -s p 1 +Enter your Python command(s). Type 'DONE' to end. +> global wp_count +> wp_count = wp_count + 1 +> print "Hit this watchpoint " + repr(wp_count) + " times!" +> DONE + +)" "In this case, since there is a reference to a global variable, \ +'wp_count', you will also need to make sure 'wp_count' exists and is \ +initialized:" R"( + +(lldb) script +>>> wp_count = 0 +>>> quit() + +)" "Final Note: A warning that no watchpoint command was generated when there \ +are no syntax errors may indicate that a function was declared but never called." + ); CommandArgumentEntry arg; CommandArgumentData wp_id_arg; |