1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009 |
- /*
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Felipe Pena <felipe@php.net> |
- | Authors: Joe Watkins <joe.watkins@live.co.uk> |
- | Authors: Bob Weinand <bwoebi@php.net> |
- | Authors: Terry Ellison <terry@ellisons.org.uk> |
- +----------------------------------------------------------------------+
- */
- #include "phpdbg.h"
- #include "phpdbg_help.h"
- #include "phpdbg_prompt.h"
- #include "zend.h"
- ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
- /* {{{ Commands Table */
- #define PHPDBG_COMMAND_HELP_D(name, tip, alias, action) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, action, &phpdbg_prompt_commands[16], 0, NULL, (bool) 0}
- const phpdbg_command_t phpdbg_help_commands[] = {
- PHPDBG_COMMAND_HELP_D(aliases, "show alias list", 'a', phpdbg_do_help_aliases),
- PHPDBG_COMMAND_HELP_D(options, "command line options", 0, NULL),
- PHPDBG_COMMAND_HELP_D(overview, "help overview", 0, NULL),
- PHPDBG_COMMAND_HELP_D(phpdbginit, "phpdbginit file format", 0, NULL),
- PHPDBG_COMMAND_HELP_D(syntax, "syntax overview", 0, NULL),
- PHPDBG_END_COMMAND
- }; /* }}} */
- /* {{{ pretty_print. Formatting escapes and wrapping text in a string before printing it. */
- void pretty_print(char *text)
- {
- char *new, *p, *q;
- const char *prompt_escape = phpdbg_get_prompt();
- size_t prompt_escape_len = strlen(prompt_escape);
- size_t prompt_len = strlen(PHPDBG_G(prompt)[0]);
- const char *bold_on_escape = PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "\033[1m" : "";
- const char *bold_off_escape = PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "\033[0m" : "";
- size_t bold_escape_len = strlen(bold_on_escape);
- uint32_t term_width = phpdbg_get_terminal_width();
- uint32_t size = 0;
- int in_bold = 0;
- char *last_new_blank = NULL; /* position in new buffer of last blank char */
- uint32_t last_blank_count = 0; /* printable char offset of last blank char */
- uint32_t line_count = 0; /* number printable chars on current line */
- /* First pass calculates a safe size for the pretty print version */
- for (p = text; *p; p++) {
- if (UNEXPECTED(p[0] == '*') && p[1] == '*') {
- size += bold_escape_len - 2;
- p++;
- } else if (UNEXPECTED(p[0] == '$') && p[1] == 'P') {
- size += prompt_escape_len - 2;
- p++;
- } else if (UNEXPECTED(p[0] == '\\')) {
- p++;
- }
- }
- size += (p-text)+1;
- new = emalloc(size);
- /*
- * Second pass substitutes the bold and prompt escape sequences and line wrap
- *
- * ** toggles bold on and off if PHPDBG_IS_COLOURED flag is set
- * $P substitutes the prompt sequence
- * Lines are wrapped by replacing the last blank with a CR before <term width>
- * characters. (This defaults to 100 if the width can't be detected). In the
- * pathological case where no blanks are found, then the wrap occurs at the
- * first blank.
- */
- for (p = text, q = new; *p; p++) {
- if (UNEXPECTED(*p == ' ')) {
- last_new_blank = q;
- last_blank_count = line_count++;
- *q++ = ' ';
- } else if (UNEXPECTED(*p == '\n')) {
- last_new_blank = NULL;
- *q++ = *p;
- last_blank_count = 0;
- line_count = 0;
- } else if (UNEXPECTED(p[0] == '*') && p[1] == '*') {
- if (bold_escape_len) {
- in_bold = !in_bold;
- memcpy (q, in_bold ? bold_on_escape : bold_off_escape, bold_escape_len);
- q += bold_escape_len;
- /* bold on/off has zero print width so line count is unchanged */
- }
- p++;
- } else if (UNEXPECTED(p[0] == '$') && p[1] == 'P') {
- memcpy (q, prompt_escape, prompt_escape_len);
- q += prompt_escape_len;
- line_count += prompt_len;
- p++;
- } else if (UNEXPECTED(p[0] == '\\')) {
- p++;
- *q++ = *p;
- line_count++;
- } else {
- *q++ = *p;
- line_count++;
- }
- if (UNEXPECTED(line_count>=term_width) && last_new_blank) {
- *last_new_blank = '\n';
- last_new_blank = NULL;
- line_count -= last_blank_count;
- last_blank_count = 0;
- }
- }
- *q++ = '\0';
- if ((q-new)>size) {
- phpdbg_error("Output overrun of %" PRIu32 " bytes", (uint32_t) ((q - new) - size));
- }
- phpdbg_out("%s\n", new);
- efree(new);
- } /* }}} */
- /* {{{ summary_print. Print a summary line giving, the command, its alias and tip */
- void summary_print(phpdbg_command_t const * const cmd)
- {
- char *summary;
- spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**\n", cmd->name, cmd->alias, cmd->tip);
- pretty_print(summary);
- efree(summary);
- }
- /* {{{ get_help. Retries and formats text from the phpdbg help text table */
- static char *get_help(const char * const key)
- {
- phpdbg_help_text_t *p;
- /* Note that phpdbg_help_text is not assumed to be collated in key order. This is an
- inconvenience that means that help can't be logically grouped Not worth
- the savings */
- for (p = phpdbg_help_text; p->key; p++) {
- if (!strcmp(p->key, key)) {
- return p->text;
- }
- }
- return ""; /* return empty string to denote no match found */
- } /* }}} */
- /* {{{ get_command. Return number of matching commands from a command table.
- * Unlike the command parser, the help search is sloppy that is partial matches can occur
- * * Any single character key is taken as an alias.
- * * Other keys are matched again the table on the first len characters.
- * * This means that non-unique keys can generate multiple matches.
- * * The first matching command is returned as an OUT parameter. *
- * The rationale here is to assist users in finding help on commands. So unique matches
- * will be used to generate a help message but non-unique one will be used to list alternatives.
- */
- static int get_command(
- const char *key, size_t len, /* pointer and length of key */
- phpdbg_command_t const **command, /* address of first matching command */
- phpdbg_command_t const * commands /* command table to be scanned */
- )
- {
- const phpdbg_command_t *c;
- unsigned int num_matches = 0;
- if (len == 1) {
- for (c=commands; c->name; c++) {
- if (c->alias == key[0]) {
- num_matches++;
- if ( num_matches == 1 && command) {
- *command = c;
- }
- }
- }
- } else {
- for (c=commands; c->name; c++) {
- if (!strncmp(c->name, key, len)) {
- ++num_matches;
- if ( num_matches == 1 && command) {
- *command = c;
- }
- }
- }
- }
- return num_matches;
- } /* }}} */
- void phpdbg_do_help_cmd(char *type) { /* {{{ */
- char *help;
- if (!type) {
- pretty_print(get_help("overview!"));
- return;
- }
- help = get_help(type);
- if (!help || memcmp(help, "", sizeof("")) == SUCCESS) {
- pretty_print(get_help("overview!"));
- pretty_print(
- "\nrequested help page could not be found");
- return;
- }
- pretty_print(help);
- } /* }}} */
- PHPDBG_COMMAND(help) /* {{{ */
- {
- phpdbg_command_t const *cmd;
- int n;
- if (!param || param->type == EMPTY_PARAM) {
- pretty_print(get_help("overview!"));
- return SUCCESS;
- }
- if (param && param->type == STR_PARAM) {
- n = get_command(param->str, param->len, &cmd, phpdbg_prompt_commands);
- if (n==1) {
- summary_print(cmd);
- pretty_print(get_help(cmd->name));
- return SUCCESS;
- } else if (n>1) {
- if (param->len > 1) {
- for (cmd=phpdbg_prompt_commands; cmd->name; cmd++) {
- if (!strncmp(cmd->name, param->str, param->len)) {
- summary_print(cmd);
- }
- }
- pretty_print(get_help("duplicate!"));
- return SUCCESS;
- } else {
- phpdbg_error("Internal help error, non-unique alias \"%c\"", param->str[0]);
- return FAILURE;
- }
- } else { /* no prompt command found so try help topic */
- n = get_command( param->str, param->len, &cmd, phpdbg_help_commands);
- if (n>0) {
- if (cmd->alias == 'a') { /* help aliases executes a canned routine */
- return cmd->handler(param);
- } else {
- pretty_print(get_help(cmd->name));
- return SUCCESS;
- }
- } else {
- phpdbg_error("No help topic found for %s", param->str);
- }
- }
- }
- return FAILURE;
- } /* }}} */
- PHPDBG_HELP(aliases) /* {{{ */
- {
- const phpdbg_command_t *c, *c_sub;
- int len;
- /* Print out aliases for all commands except help as this one comes last */
- phpdbg_writeln("Below are the aliased, short versions of all supported commands");
- for(c = phpdbg_prompt_commands; c->name; c++) {
- if (c->alias && c->alias != 'h') {
- phpdbg_writeln(" %c %-20s %s", c->alias, c->name, c->tip);
- if (c->subs) {
- len = 20 - 1 - c->name_len;
- for(c_sub = c->subs; c_sub->alias; c_sub++) {
- if (c_sub->alias) {
- phpdbg_writeln(" %c %c %s %-*s %s",
- c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip);
- }
- }
- }
- }
- }
- /* Print out aliases for help as this one comes last, with the added text on how aliases are used */
- get_command("h", 1, &c, phpdbg_prompt_commands);
- phpdbg_writeln(" %c %-20s %s\n", c->alias, c->name, c->tip);
- len = 20 - 1 - c->name_len;
- for(c_sub = c->subs; c_sub->alias; c_sub++) {
- if (c_sub->alias) {
- phpdbg_writeln(" %c %c %s %-*s %s",
- c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip);
- }
- }
- pretty_print(get_help("aliases!"));
- return SUCCESS;
- } /* }}} */
- /* {{{ Help Text Table
- * Contains help text entries keyed by a lowercase ascii key.
- * Text is in ascii and enriched by a simple markup:
- * ** toggles bold font emphasis.
- * $P insert an bold phpdbg> prompt.
- * \ escapes the following character. Note that this is itself escaped inside string
- * constants so \\\\ is required to output a single \ e.g. as in namespace names.
- *
- * Text will be wrapped according to the STDOUT terminal width, so paragraphs are
- * flowed using the C stringizing and the CR definition. Also note that entries
- * are collated in alphabetic order on key.
- *
- * Also note the convention that help text not directly referenceable as a help param
- * has a key ending in !
- */
- #define CR "\n"
- phpdbg_help_text_t phpdbg_help_text[] = {
- /******************************** General Help Topics ********************************/
- {"overview!", CR
- "**phpdbg** is a lightweight, powerful and easy to use debugging platform for PHP5.4+" CR
- "It supports the following commands:" CR CR
- "**Information**" CR
- " **list** list PHP source" CR
- " **info** displays information on the debug session" CR
- " **print** show opcodes" CR
- " **frame** select a stack frame and print a stack frame summary" CR
- " **generator** show active generators or select a generator frame" CR
- " **back** shows the current backtrace" CR
- " **help** provide help on a topic" CR CR
- "**Starting and Stopping Execution**" CR
- " **exec** set execution context" CR
- " **stdin** set executing script from stdin" CR
- " **run** attempt execution" CR
- " **step** continue execution until other line is reached" CR
- " **continue** continue execution" CR
- " **until** continue execution up to the given location" CR
- " **next** continue execution up to the given location and halt on the first line after it" CR
- " **finish** continue up to end of the current execution frame" CR
- " **leave** continue up to end of the current execution frame and halt after the calling instruction" CR
- " **break** set a breakpoint at the specified target" CR
- " **watch** set a watchpoint on $variable" CR
- " **clear** clear one or all breakpoints" CR
- " **clean** clean the execution environment" CR CR
- "**Miscellaneous**" CR
- " **set** set the phpdbg configuration" CR
- " **source** execute a phpdbginit script" CR
- " **register** register a phpdbginit function as a command alias" CR
- " **sh** shell a command" CR
- " **ev** evaluate some code" CR
- " **quit** exit phpdbg" CR CR
- "Type **help <command>** or (**help alias**) to get detailed help on any of the above commands, "
- "for example **help list** or **h l**. Note that help will also match partial commands if unique "
- "(and list out options if not unique), so **help exp** will give help on the **export** command, "
- "but **help ex** will list the summary for **exec** and **export**." CR CR
- "Type **help aliases** to show a full alias list, including any registered phpdbginit functions" CR
- "Type **help syntax** for a general introduction to the command syntax." CR
- "Type **help options** for a list of phpdbg command line options." CR
- "Type **help phpdbginit** to show how to customize the debugger environment."
- },
- {"options", CR
- "Below are the command line options supported by phpdbg" CR CR
- /* note the extra 4 space index in because of the extra **** */
- "**Command Line Options and Flags**" CR
- " **Option** **Example Argument** **Description**" CR
- " **-c** **-c**/my/php.ini Set php.ini file to load" CR
- " **-d** **-d**memory_limit=4G Set a php.ini directive" CR
- " **-n** Disable default php.ini" CR
- " **-q** Suppress welcome banner" CR
- " **-v** Enable oplog output" CR
- " **-b** Disable colour" CR
- " **-i** **-i**my.init Set .phpdbginit file" CR
- " **-I** Ignore default .phpdbginit" CR
- " **-r** Run execution context" CR
- " **-rr** Run execution context and quit after execution (not respecting breakpoints)" CR
- " **-e** Generate extended information for debugger/profiler" CR
- " **-E** Enable step through eval, careful!" CR
- " **-s** **-s=**, **-s**=foo Read code to execute from stdin with an optional delimiter" CR
- " **-S** **-S**cli Override SAPI name, careful!" CR
- " **-p** **-p**, **-p=func**, **-p* ** Output opcodes and quit" CR
- " **-h** Print the help overview" CR
- " **-V** Print version number" CR
- " **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
- "argument after it" CR CR
- "**Reading from stdin**" CR CR
- "The **-s** option allows inputting a script to execute directly from stdin. The given delimiter "
- "(\"foo\" in the example) needs to be specified at the end of the input on its own line, followed by "
- "a line break. If **-rr** has been specified, it is allowed to omit the delimiter (**-s=**) and "
- "it will read until EOF. See also the help entry for the **stdin** command." CR CR
- "**Opcode output**" CR CR
- "Outputting opcodes requires that a file path is passed as last argument. Modes of execution:" CR
- "**-p** Outputs the main execution context" CR
- "**-p* **Outputs all opcodes in the whole file (including classes and functions)" CR
- "**-p=function_name** Outputs opcodes of a given function in the file" CR
- "**-p=class_name::** Outputs opcodes of all the methods of a given class" CR
- "**-p=class_name::method** Outputs opcodes of a given method"
- },
- {"phpdbginit", CR
- "Phpdbg uses an debugger script file to initialize the debugger context. By default, phpdbg looks "
- "for the file named **.phpdbginit** in the current working directory. This location can be "
- "overridden on the command line using the **-i** switch (see **help options** for a more "
- "details)." CR CR
- "Debugger scripts can also be executed using the **source** command." CR CR
- "A script file can contain a sequence of valid debugger commands, comments and embedded PHP "
- "code. " CR CR
- "Comment lines are prefixed by the **#** character. Note that comments are only allowed in script "
- "files and not in interactive sessions." CR CR
- "PHP code is delimited by the start and end escape tags **<:** and **:>**. PHP code can be used "
- "to define application context for a debugging session and also to extend the debugger by defining "
- "and **register** PHP functions as new commands." CR CR
- "Also note that executing a **clear** command will cause the current **phpdbginit** to be reparsed "
- "/ reloaded."
- },
- {"syntax", CR
- "Commands start with a keyword, and some (**break**, "
- "**info**, **set**, **print** and **list**) may include a subcommand keyword. All keywords are "
- "lower case but also have a single letter alias that may be used as an alternative to typing in the"
- "keyword in full. Note some aliases are uppercase, and that keywords cannot be abbreviated other "
- "than by substitution by the alias." CR CR
- "Some commands take an argument. Arguments are typed according to their format:" CR
- " * **omitted**" CR
- " * **address** **0x** followed by a hex string" CR
- " * **number** an optionally signed number" CR
- " * **method** a valid **Class::methodName** expression" CR
- " * **func#op** a valid **Function name** follow by # and an integer" CR
- " * **method#op** a valid **Class::methodName** follow by # and an integer" CR
- " * **string** a general string" CR
- " * **function** a valid **Function name**" CR
- " * **file:line** a valid **filename** follow by : and an integer" CR CR
- "In some cases the type of the argument enables the second keyword to be omitted." CR CR
- "Type **help** for an overview of all commands and type **help <command>** to get detailed help "
- "on any specific command." CR CR
- "**Valid Examples**" CR CR
- " $P quit" CR
- " $P q" CR
- " Quit the debugger" CR CR
- " $P ev $total[2]" CR
- " Evaluate and print the variable $total[2] in the current stack frame" CR
- " " CR
- " $P break 200" CR
- " $P b my_source.php:200" CR
- " Break at line 200 in the current source and in file **my_source.php**. " CR CR
- " $P b @ ClassX::get_args if $arg[0] == \"fred\"" CR
- " $P b ~ 3" CR
- " Break at ClassX::get_args() if $arg[0] == \"fred\" and delete breakpoint 3" CR CR
- "**Examples of invalid commands**" CR
- " $P #This is a comment" CR
- " Comments introduced by the **#** character are only allowed in **phpdbginit** script files."
- },
- /******************************** Help Codicils ********************************/
- {"aliases!", CR
- "Note that aliases can be used for either command or sub-command keywords or both, so **info b** "
- "is a synonym for **info break** and **l func** for **list func**, etc." CR CR
- "Note that help will also accept any alias as a parameter and provide help on that command, for example **h p** will provide help on the print command."
- },
- {"duplicate!", CR
- "Parameter is not unique. For detailed help select help on one of the above commands."
- },
- /******************************** Help on Commands ********************************/
- {"back",
- "Provide a formatted backtrace using the standard debug_backtrace() functionality. An optional "
- "unsigned integer argument specifying the maximum number of frames to be traced; if omitted then "
- "a complete backtrace is given." CR CR
- "**Examples**" CR CR
- " $P back 5" CR
- " $P t " CR
- " " CR
- "A backtrace can be executed at any time during execution."
- },
- {"break",
- "Breakpoints can be set at a range of targets within the execution environment. Execution will "
- "be paused if the program flow hits a breakpoint. The break target can be one of the following "
- "types:" CR CR
- " **Target** **Alias** **Purpose**" CR
- " **at** **@** specify breakpoint by location and condition" CR
- " **del** **~** delete breakpoint by breakpoint identifier number" CR CR
- "**Break at** takes two arguments. The first is any valid target. The second "
- "is a valid PHP expression which will trigger the break in "
- "execution, if evaluated as true in a boolean context at the specified target." CR CR
- "Note that breakpoints can also be disabled and re-enabled by the **set break** command." CR CR
- "**Examples**" CR CR
- " $P break test.php:100" CR
- " $P b test.php:100" CR
- " Break execution at line 100 of test.php" CR CR
- " $P break 200" CR
- " $P b 200" CR
- " Break execution at line 200 of the currently PHP script file" CR CR
- " $P break \\\\mynamespace\\\\my_function" CR
- " $P b \\\\mynamespace\\\\my_function" CR
- " Break execution on entry to \\\\mynamespace\\\\my_function" CR CR
- " $P break classX::method" CR
- " $P b classX::method" CR
- " Break execution on entry to classX::method" CR CR
- " $P break 0x7ff68f570e08" CR
- " $P b 0x7ff68f570e08" CR
- " Break at the opline at the address 0x7ff68f570e08" CR CR
- " $P break my_function#14" CR
- " $P b my_function#14" CR
- " Break at the opline #14 of the function my_function" CR CR
- " $P break \\\\my\\\\class::method#2" CR
- " $P b \\\\my\\\\class::method#2" CR
- " Break at the opline #2 of the method \\\\my\\\\class::method" CR CR
- " $P break test.php:#3" CR
- " $P b test.php:#3" CR
- " Break at opline #3 in test.php" CR CR
- " $P break if $cnt > 10" CR
- " $P b if $cnt > 10" CR
- " Break when the condition ($cnt > 10) evaluates to true" CR CR
- " $P break at phpdbg::isGreat if $opt == 'S'" CR
- " $P break @ phpdbg::isGreat if $opt == 'S'" CR
- " Break at any opcode in phpdbg::isGreat when the condition ($opt == 'S') is true" CR CR
- " $P break at test.php:20 if !isset($x)" CR
- " Break at every opcode on line 20 of test.php when the condition evaluates to true" CR CR
- " $P break ZEND_ADD" CR
- " $P b ZEND_ADD" CR
- " Break on any occurrence of the opcode ZEND_ADD" CR CR
- " $P break del 2" CR
- " $P b ~ 2" CR
- " Remove breakpoint 2" CR CR
- "Note: Conditional breaks are costly in terms of runtime overhead. Use them only when required "
- "as they significantly slow execution." CR CR
- "Note: An address is only valid for the current compilation."
- },
- {"clean",
- "Classes, constants or functions can only be declared once in PHP. You may experience errors "
- "during a debug session if you attempt to recompile a PHP source. The clean command clears "
- "the Zend runtime tables which holds the sets of compiled classes, constants and functions, "
- "releasing any associated storage back into the storage pool. This enables recompilation to "
- "take place." CR CR
- "Note that you cannot selectively trim any of these resource pools. You can only do a complete "
- "clean."
- },
- {"clear",
- "Clearing breakpoints means you can once again run code without interruption." CR CR
- "Note: use break delete N to clear a specific breakpoint." CR CR
- "Note: if all breakpoints are cleared, then the PHP script will run until normal completion."
- },
- {"ev",
- "The **ev** command takes a string expression which it evaluates and then displays. It "
- "evaluates in the context of the lowest (that is the executing) frame, unless this has first "
- "been explicitly changed by issuing a **frame** command. " CR CR
- "**Examples**" CR CR
- " $P ev $variable" CR
- " Will print_r($variable) on the console, if it is defined" CR CR
- " $P ev $variable = \"Hello phpdbg :)\"" CR
- " Will set $variable in the current scope" CR CR
- "Note that **ev** allows any valid PHP expression including assignments, function calls and "
- "other write statements. This enables you to change the environment during execution, so care "
- "is needed here. You can even call PHP functions which have breakpoints defined. " CR CR
- "Note: **ev** will always show the result, so do not prefix the code with **return**"
- },
- {"exec",
- "The **exec** command sets the execution context, that is the script to be executed. The "
- "execution context must be defined either by executing the **exec** command or by using the "
- "**-e** command line option." CR CR
- "Note that the **exec** command also can be used to replace a previously defined execution "
- "context." CR CR
- "**Examples**" CR CR
- " $P exec /tmp/script.php" CR
- " $P e /tmp/script.php" CR
- " Set the execution context to **/tmp/script.php**"
- },
- {"stdin",
- "The **stdin** command takes a string serving as delimiter. It will then read all the input from "
- "stdin until encountering the given delimiter on a standalone line. It can also be passed at "
- "startup using the **-s=** command line option (the delimiter then is optional if **-rr** is "
- "also passed - in that case it will just read until EOF)." CR
- "This input will be then compiled as PHP code and set as execution context." CR CR
- "**Example**" CR CR
- " $P stdin foo" CR
- " <?php" CR
- " echo \"Hello, world!\\n\";" CR
- " foo"
- },
- //*********** Does F skip any breakpoints lower stack frames or only the current??
- {"finish",
- "The **finish** command causes control to be passed back to the vm, continuing execution. Any "
- "breakpoints that are encountered within the current stack frame will be skipped. Execution "
- "will then continue until the next breakpoint after leaving the stack frame or until "
- "completion of the script" CR CR
- "Note when **step**ping is enabled, any opcode steps within the current stack frame are also "
- "skipped. "CR CR
- "Note **finish** will trigger a \"not executing\" error if not executing."
- },
- {"frame",
- "The **frame** takes an optional integer argument. If omitted, then the current frame is displayed. "
- "If specified, then the current scope is set to the corresponding frame listed in a **back** trace. "
- "This can be used to allowing access to the variables in a higher stack frame than that currently being executed." CR CR
- "**Examples**" CR CR
- " $P frame 2" CR
- " $P ev $count" CR
- " Go to frame 2 and print out variable **$count** in that frame" CR CR
- "Note that this frame scope is discarded when execution continues, with the execution frame "
- "then reset to the lowest executing frame."
- },
- {"generator",
- "The **generator** command takes an optional integer argument. If omitted, then a list of the "
- "currently active generators is displayed. If specified then the current scope is set to the frame "
- "of the generator with the corresponding object handle. This can be used to inspect any generators "
- "not in the current **back** trace." CR CR
- "**Examples**" CR CR
- " $P generator" CR
- " List of generators, with the #id being the object handle, e.g.:" CR
- " #3: my_generator(argument=\"value\") at test.php:5" CR
- " $P g 3" CR
- " $P ev $i" CR
- " Go to frame of generator with object handle 3 and print out variable **$i** in that frame" CR CR
- "Note that this frame scope is discarded when execution continues, with the execution frame "
- "then reset to the lowest executing frame."
- },
- {"info",
- "**info** commands provide quick access to various types of information about the PHP environment" CR
- "By default general information about environment and PHP build is shown." CR
- "Specific info commands are show below:" CR CR
- " **Target** **Alias** **Purpose**" CR
- " **break** **b** show current breakpoints" CR
- " **files** **F** show included files" CR
- " **classes** **c** show loaded classes" CR
- " **funcs** **f** show loaded functions" CR
- " **error** **e** show last error" CR
- " **constants** **d** show user-defined constants" CR
- " **vars** **v** show active variables" CR
- " **globals** **g** show superglobal variables" CR
- " **literal** **l** show active literal constants" CR
- " **memory** **m** show memory manager stats"
- },
- // ******** same issue about breakpoints in called frames
- {"leave",
- "The **leave** command causes control to be passed back to the vm, continuing execution. Any "
- "breakpoints that are encountered within the current stack frame will be skipped. In effect a "
- "temporary breakpoint is associated with any return opcode, so that a break in execution occurs "
- "before leaving the current stack frame. This allows inspection / modification of any frame "
- "variables including the return value before it is returned" CR CR
- "**Examples**" CR CR
- " $P leave" CR
- " $P L" CR CR
- "Note when **step**ping is enabled, any opcode steps within the current stack frame are also "
- "skipped. "CR CR
- "Note **leave** will trigger a \"not executing\" error if not executing."
- },
- {"list",
- "The list command displays source code for the given argument. The target type is specified by "
- "a second subcommand keyword:" CR CR
- " **Type** **Alias** **Purpose**" CR
- " **lines** **l** List N lines from the current execution point" CR
- " **func** **f** List the complete source for a specified function" CR
- " **method** **m** List the complete source for a specified class::method" CR
- " **class** **c** List the complete source for a specified class" CR CR
- "Note that the context of **lines**, **func** and **method** can be determined by parsing the "
- "argument, so these subcommands are optional. However, you must specify the **class** keyword "
- "to list off a class." CR CR
- "**Examples**" CR CR
- " $P list 2" CR
- " $P l l 2" CR
- " List the next 2 lines from the current file" CR CR
- " $P list my_function" CR
- " $P l f my_function" CR
- " List the source of the function **my_function**" CR CR
- //************ ????
- " $P list func .mine" CR
- " $P l f .mine" CR
- " List the source of the method **mine** from the active class in scope" CR CR
- " $P list m my::method" CR
- " $P l my::method" CR
- " List the source of **my::method**" CR CR
- " $P list c myClass" CR
- " $P l c myClass" CR
- " List the source of **myClass**" CR CR
- "Note that functions and classes can only be listed if the corresponding classes and functions "
- "table in the Zend executor has a corresponding entry. You can use the compile command to "
- "populate these tables for a given execution context."
- },
- {"continue",
- "Continue with execution after hitting a break or watchpoint" CR CR
- "**Examples**" CR CR
- " $P continue" CR
- " $P c" CR
- " Continue executing until the next break or watchpoint" CR CR
- "Note **continue** will trigger a \"not running\" error if not executing."
- },
- {"print",
- "By default, print will show the opcodes of the current execution context." CR
- "Other printing commands give access to instruction information." CR
- "Specific printers loaded are show below:" CR CR
- " **Type** **Alias** **Purpose**" CR
- " **exec** **e** print out the instructions in the execution context" CR
- " **opline** **o** print out the instruction in the current opline" CR
- " **class** **c** print out the instructions in the specified class" CR
- " **method** **m** print out the instructions in the specified method" CR
- " **func** **f** print out the instructions in the specified function" CR
- " **stack** **s** print out the instructions in the current stack" CR CR
- "In case passed argument does not match a specific printing command, it will treat it as function or method name and print its opcodes" CR CR
- "**Examples**" CR CR
- " $P print class \\\\my\\\\class" CR
- " $P p c \\\\my\\\\class" CR
- " Print the instructions for the methods in \\\\my\\\\class" CR CR
- " $P print method \\\\my\\\\class::method" CR
- " $P p m \\\\my\\\\class::method" CR
- " Print the instructions for \\\\my\\\\class::method" CR CR
- " $P print func .getSomething" CR
- " $P p f .getSomething" CR
- //************* Check this local method scope
- " Print the instructions for ::getSomething in the active scope" CR CR
- " $P print func my_function" CR
- " $P p f my_function" CR
- " Print the instructions for the global function my_function" CR CR
- " $P print opline" CR
- " $P p o" CR
- " Print the instruction for the current opline" CR CR
- " $P print exec" CR
- " $P p e" CR
- " Print the instructions for the execution context" CR CR
- " $P print stack" CR
- " $P p s" CR
- " Print the instructions for the current stack"
- },
- {"register",
- //******* Needs a general explanation of the how registered functions work
- "Register any global function for use as a command in phpdbg console" CR CR
- "**Examples**" CR CR
- " $P register scandir" CR
- " $P R scandir" CR
- " Will register the scandir function for use in phpdbg" CR CR
- "Note: arguments passed as strings, return (if present) print_r'd on console"
- },
- {"run",
- "Enter the vm, starting execution. Execution will then continue until the next breakpoint "
- "or completion of the script. Add parameters you want to use as $argv. Add a trailing "
- "**< filename** for reading STDIN from a file." CR CR
- "**Examples**" CR CR
- " $P run" CR
- " $P r" CR
- " Will cause execution of the context, if it is set" CR CR
- " $P r test < foo.txt" CR
- " Will execute with $argv[1] == \"test\" and read from the foo.txt file for STDIN" CR CR
- "Note that the execution context must be set. If not previously compiled, then the script will "
- "be compiled before execution."
- },
- {"set",
- "The **set** command is used to configure how phpdbg looks and behaves. Specific set commands "
- "are as follows:" CR CR
- " **Type** **Alias** **Purpose**" CR
- " **prompt** **p** set the prompt" CR
- " **color** **c** set color <element> <color>" CR
- " **colors** **C** set colors [<on|off>]" CR
- " **break** **b** set break **id** <on|off>" CR
- " **breaks** **B** set breaks [<on|off>]" CR
- " **quiet** **q** set quiet [<on|off>]" CR
- " **stepping** **s** set stepping [<opcode|line>]" CR
- " **refcount** **r** set refcount [<on|off>] " CR CR
- "Valid colors are **none**, **white**, **red**, **green**, **yellow**, **blue**, **purple**, "
- "**cyan** and **black**. All colours except **none** can be followed by an optional "
- "**-bold** or **-underline** qualifier." CR CR
- "Color elements can be one of **prompt**, **notice**, or **error**." CR CR
- "**Examples**" CR CR
- " $P S C on" CR
- " Set colors on" CR CR
- " $P set p >" CR
- " $P set color prompt white-bold" CR
- " Set the prompt to a bold >" CR CR
- " $P S c error red-bold" CR
- " Use red bold for errors" CR CR
- " $P S refcount on" CR
- " Enable refcount display when hitting watchpoints" CR CR
- " $P S b 4 off" CR
- " Temporarily disable breakpoint 4. This can be subsequently re-enabled by a **S b 4 on**." CR
- //*********** check oplog syntax
- },
- {"sh",
- "Direct access to shell commands saves having to switch windows/consoles" CR CR
- "**Examples**" CR CR
- " $P sh ls /usr/src/php-src" CR
- " Will execute ls /usr/src/php-src, displaying the output in the console"
- //*********** what does this mean????Note: read only commands please!
- },
- {"source",
- "Sourcing a **phpdbginit** script during your debugging session might save some time." CR CR
- "**Examples**" CR CR
- " $P source /my/init" CR
- " $P < /my/init" CR
- " Will execute the phpdbginit file at /my/init" CR CR
- },
- {"export",
- "Exporting breakpoints allows you to share, and or save your current debugging session" CR CR
- "**Examples**" CR CR
- " $P export /my/exports" CR
- " $P > /my/exports" CR
- " Will export all breakpoints to /my/exports" CR CR
- },
- {"step",
- "Execute opcodes until next line" CR CR
- "**Examples**" CR CR
- " $P s" CR
- " Will continue and break again in the next encountered line" CR CR
- },
- {"next",
- "The **next** command causes control to be passed back to the vm, continuing execution. Any "
- "breakpoints that are encountered before the next source line will be skipped. Execution will"
- "be stopped when that line is left." CR CR
- "Note when **step**ping is enabled, any opcode steps within the current line are also skipped. "CR CR
- "Note that if the next line is **not** executed then **all** subsequent breakpoints will be "
- "skipped. " CR CR
- "Note **next** will trigger a \"not executing\" error if not executing."
- },
- {"until",
- "The **until** command causes control to be passed back to the vm, continuing execution. Any "
- "breakpoints that are encountered before the next source line will be skipped. Execution "
- "will then continue until the next breakpoint or completion of the script" CR CR
- "Note when **step**ping is enabled, any opcode steps within the current line are also skipped. "CR CR
- "Note that if the next line is **not** executed then **all** subsequent breakpoints will be "
- "skipped. " CR CR
- "Note **until** will trigger a \"not executing\" error if not executing."
- },
- {"watch",
- "Sets watchpoints on variables as long as they are defined" CR
- "Passing no parameter to **watch**, lists all actually active watchpoints" CR CR
- "**Format for $variable**" CR CR
- " **$var** Variable $var" CR
- " **$var[]** All array elements of $var" CR
- " **$var->** All properties of $var" CR
- " **$var->a** Property $var->a" CR
- " **$var[b]** Array element with key b in array $var" CR CR
- "Subcommands of **watch**:" CR CR
- " **Type** **Alias** **Purpose**" CR
- " **array** **a** Sets watchpoint on array/object to observe if an entry is added or removed" CR
- " **recursive** **r** Watches variable recursively and automatically adds watchpoints if some entry is added to an array/object" CR
- " **delete** **d** Removes watchpoint" CR CR
- "Note when **recursive** watchpoints are removed, watchpoints on all the children are removed too" CR CR
- "**Examples**" CR CR
- " $P watch" CR
- " List currently active watchpoints" CR CR
- " $P watch $array" CR
- " $P w $array" CR
- " Set watchpoint on $array" CR CR
- " $P watch recursive $obj->" CR
- " $P w r $obj->" CR
- " Set recursive watchpoint on $obj->" CR CR
- " $P watch delete $obj->a" CR
- " $P w d $obj->a" CR
- " Remove watchpoint $obj->a" CR CR
- "Technical note: If using this feature with a debugger, you will get many segmentation faults, each time when a memory page containing a watched address is hit." CR
- " You then you can continue, phpdbg will remove the write protection, so that the program can continue." CR
- " If phpdbg could not handle that segfault, the same segfault is triggered again and this time phpdbg will abort."
- },
- {NULL, NULL /* end of table marker */}
- }; /* }}} */
|