123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638 |
- /*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2016 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: |
- | http://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> |
- +----------------------------------------------------------------------+
- */
- #include "zend.h"
- #include "zend_hash.h"
- #include "phpdbg.h"
- #include "phpdbg_bp.h"
- #include "phpdbg_utils.h"
- #include "phpdbg_opcode.h"
- #include "zend_globals.h"
- ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
- /* {{{ private api functions */
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array* TSRMLS_DC);
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_symbol(zend_function* TSRMLS_DC);
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_method(zend_op_array* TSRMLS_DC);
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opline(phpdbg_opline_ptr_t TSRMLS_DC);
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opcode(zend_uchar TSRMLS_DC);
- static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execute_data *execute_data TSRMLS_DC); /* }}} */
- /*
- * Note:
- * A break point must always set the correct id and type
- * A set breakpoint function must always map new points
- */
- static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC)
- {
- zend_hash_index_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id), (void**) &table, sizeof(void*), NULL);
- }
- #define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table TSRMLS_CC)
- #define PHPDBG_BREAK_UNMAPPING(id) \
- zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id))
- #define PHPDBG_BREAK_INIT(b, t) do {\
- b.id = PHPDBG_G(bp_count)++; \
- b.type = t; \
- b.disabled = 0;\
- b.hits = 0; \
- } while(0)
- static void phpdbg_file_breaks_dtor(void *data) /* {{{ */
- {
- phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) data;
- efree((char*)bp->filename);
- } /* }}} */
- static void phpdbg_class_breaks_dtor(void *data) /* {{{ */
- {
- phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t*) data;
- efree((char*)bp->class_name);
- efree((char*)bp->func_name);
- } /* }}} */
- static void phpdbg_opline_class_breaks_dtor(void *data) /* {{{ */
- {
- zend_hash_destroy((HashTable *)data);
- } /* }}} */
- static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */
- {
- phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) data;
- if (bp->class_name) {
- efree((char*)bp->class_name);
- }
- if (bp->func_name) {
- efree((char*)bp->func_name);
- }
- } /* }}} */
- PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */
- {
- if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
- HashPosition position[2];
- HashTable **table = NULL;
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) {
- phpdbg_breakbase_t *brake;
- for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
- zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex((*table), &position[1])) {
- brake->hits = 0;
- }
- }
- }
- } /* }}} */
- PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
- {
- HashPosition position[2];
- HashTable **table = NULL;
- zend_ulong id = 0L;
- if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
- phpdbg_notice(
- "Exporting %d breakpoints",
- zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
- /* this only looks like magic, it isn't */
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) {
- phpdbg_breakbase_t *brake;
- zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]);
- for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
- zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex((*table), &position[1])) {
- if (brake->id == id) {
- switch (brake->type) {
- case PHPDBG_BREAK_FILE: {
- fprintf(handle,
- "break %s:%lu\n",
- ((phpdbg_breakfile_t*)brake)->filename,
- ((phpdbg_breakfile_t*)brake)->line);
- } break;
- case PHPDBG_BREAK_SYM: {
- fprintf(handle,
- "break %s\n",
- ((phpdbg_breaksymbol_t*)brake)->symbol);
- } break;
- case PHPDBG_BREAK_METHOD: {
- fprintf(handle,
- "break %s::%s\n",
- ((phpdbg_breakmethod_t*)brake)->class_name,
- ((phpdbg_breakmethod_t*)brake)->func_name);
- } break;
- case PHPDBG_BREAK_METHOD_OPLINE: {
- fprintf(handle,
- "break %s::%s#%ld\n",
- ((phpdbg_breakopline_t*)brake)->class_name,
- ((phpdbg_breakopline_t*)brake)->func_name,
- ((phpdbg_breakopline_t*)brake)->opline_num);
- } break;
- case PHPDBG_BREAK_FUNCTION_OPLINE: {
- fprintf(handle,
- "break %s#%ld\n",
- ((phpdbg_breakopline_t*)brake)->func_name,
- ((phpdbg_breakopline_t*)brake)->opline_num);
- } break;
- case PHPDBG_BREAK_FILE_OPLINE: {
- fprintf(handle,
- "break %s:#%ld\n",
- ((phpdbg_breakopline_t*)brake)->class_name,
- ((phpdbg_breakopline_t*)brake)->opline_num);
- } break;
- case PHPDBG_BREAK_OPCODE: {
- fprintf(handle,
- "break %s\n",
- ((phpdbg_breakop_t*)brake)->name);
- } break;
- case PHPDBG_BREAK_COND: {
- phpdbg_breakcond_t *conditional = (phpdbg_breakcond_t*) brake;
- if (conditional->paramed) {
- switch (conditional->param.type) {
- case STR_PARAM:
- fprintf(handle,
- "break at %s if %s\n", conditional->param.str, conditional->code);
- break;
- case METHOD_PARAM:
- fprintf(handle,
- "break at %s::%s if %s\n",
- conditional->param.method.class, conditional->param.method.name,
- conditional->code);
- break;
- case FILE_PARAM:
- fprintf(handle,
- "break at %s:%lu if %s\n",
- conditional->param.file.name, conditional->param.file.line,
- conditional->code);
- break;
- default: { /* do nothing */ } break;
- }
- } else {
- fprintf(
- handle, "break if %s\n", conditional->code);
- }
- } break;
- }
- }
- }
- }
- }
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */
- {
- php_stream_statbuf ssb;
- char realpath[MAXPATHLEN];
-
- if (php_stream_stat_path(path, &ssb) != FAILURE) {
- if (ssb.sb.st_mode & (S_IFREG|S_IFLNK)) {
- HashTable *broken;
- phpdbg_breakfile_t new_break;
- size_t path_len = 0L;
-
- if (VCWD_REALPATH(path, realpath)) {
- path = realpath;
- }
- path_len = strlen(path);
-
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- path, path_len, (void**)&broken) == FAILURE) {
- HashTable breaks;
- zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0);
- zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- path, path_len, &breaks, sizeof(HashTable),
- (void**)&broken);
- }
- if (!zend_hash_index_exists(broken, line_num)) {
- PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE);
- new_break.filename = estrndup(path, path_len);
- new_break.line = line_num;
- zend_hash_index_update(
- broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL);
- phpdbg_notice("Breakpoint #%d added at %s:%ld",
- new_break.id, new_break.filename, new_break.line);
- PHPDBG_BREAK_MAPPING(new_break.id, broken);
- } else {
- phpdbg_error("Breakpoint at %s:%ld exists", path, line_num);
- }
- } else {
- phpdbg_error("Cannot set breakpoint in %s, it is not a regular file", path);
- }
- } else {
- phpdbg_error("Cannot stat %s, it does not exist", path);
- }
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len TSRMLS_DC) /* {{{ */
- {
- if (!zend_hash_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) {
- phpdbg_breaksymbol_t new_break;
- PHPDBG_G(flags) |= PHPDBG_HAS_SYM_BP;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_SYM);
- new_break.symbol = estrndup(name, name_len);
- zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol,
- name_len, &new_break, sizeof(phpdbg_breaksymbol_t), NULL);
- phpdbg_notice("Breakpoint #%d added at %s",
- new_break.id, new_break.symbol);
- PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
- } else {
- phpdbg_notice("Breakpoint exists at %s", name);
- }
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char *func_name TSRMLS_DC) /* {{{ */
- {
- HashTable class_breaks, *class_table;
- size_t class_len = strlen(class_name);
- size_t func_len = strlen(func_name);
- char *lcname = zend_str_tolower_dup(func_name, func_len);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name,
- class_len, (void**)&class_table) != SUCCESS) {
- zend_hash_init(&class_breaks, 8, NULL, phpdbg_class_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
- class_name, class_len,
- (void**)&class_breaks, sizeof(HashTable), (void**)&class_table);
- }
- if (!zend_hash_exists(class_table, lcname, func_len)) {
- phpdbg_breakmethod_t new_break;
- PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_BP;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_METHOD);
- new_break.class_name = estrndup(class_name, class_len);
- new_break.class_len = class_len;
- new_break.func_name = estrndup(func_name, func_len);
- new_break.func_len = func_len;
- zend_hash_update(class_table, lcname, func_len,
- &new_break, sizeof(phpdbg_breakmethod_t), NULL);
- phpdbg_notice("Breakpoint #%d added at %s::%s",
- new_break.id, class_name, func_name);
- PHPDBG_BREAK_MAPPING(new_break.id, class_table);
- } else {
- phpdbg_notice("Breakpoint exists at %s::%s", class_name, func_name);
- }
- efree(lcname);
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ */
- {
- if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline)) {
- phpdbg_breakline_t new_break;
- PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE);
- new_break.name = NULL;
- new_break.opline = opline;
- new_break.base = NULL;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline,
- &new_break, sizeof(phpdbg_breakline_t), NULL);
- phpdbg_notice("Breakpoint #%d added at %#lx",
- new_break.id, new_break.opline);
- PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- } else {
- phpdbg_notice("Breakpoint exists at %#lx", opline);
- }
- } /* }}} */
- PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_op_array *op_array TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakline_t opline_break;
- if (op_array->last <= brake->opline_num) {
- if (brake->class_name == NULL) {
- phpdbg_error("There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num);
- } else if (brake->func_name == NULL) {
- phpdbg_error("There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num);
- } else {
- phpdbg_error("There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num);
- }
- return FAILURE;
- }
- opline_break.disabled = 0;
- opline_break.hits = 0;
- opline_break.id = brake->id;
- opline_break.opline = brake->opline = (zend_ulong)(op_array->opcodes + brake->opline_num);
- opline_break.name = NULL;
- opline_break.base = brake;
- if (op_array->scope) {
- opline_break.type = PHPDBG_BREAK_METHOD_OPLINE;
- } else if (op_array->function_name) {
- opline_break.type = PHPDBG_BREAK_FUNCTION_OPLINE;
- } else {
- opline_break.type = PHPDBG_BREAK_FILE_OPLINE;
- }
- PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t), NULL);
- return SUCCESS;
- } /* }}} */
- PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC) /* {{{ */
- {
- HashTable *func_table = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE];
- HashTable *oplines_table;
- HashPosition position;
- phpdbg_breakopline_t *brake;
- if (op_array->scope != NULL &&
- zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name, op_array->scope->name_length, (void **)&func_table) == FAILURE) {
- return;
- }
- if (op_array->function_name == NULL) {
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename, strlen(op_array->filename), (void **)&oplines_table) == FAILURE) {
- return;
- }
- } else if (zend_hash_find(func_table, op_array->function_name?op_array->function_name:"", op_array->function_name?strlen(op_array->function_name):0, (void **)&oplines_table) == FAILURE) {
- return;
- }
- for (zend_hash_internal_pointer_reset_ex(oplines_table, &position);
- zend_hash_get_current_data_ex(oplines_table, (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(oplines_table, &position)) {
- if (phpdbg_resolve_op_array_break(brake, op_array TSRMLS_CC) == SUCCESS) {
- phpdbg_breakline_t *opline_break;
- zend_hash_internal_pointer_end(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- zend_hash_get_current_data(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void **)&opline_break);
- phpdbg_notice("Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)",
- brake->id,
- brake->class_name?brake->class_name:"",
- brake->class_name&&brake->func_name?"::":"",
- brake->func_name?brake->func_name:"",
- brake->opline_num,
- brake->opline);
- }
- }
- } /* }}} */
- PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC) /* {{{ */
- {
- HashTable *func_table = EG(function_table);
- zend_function *func;
- if (new_break->func_name == NULL) {
- if (EG(current_execute_data) == NULL) {
- if (PHPDBG_G(ops) != NULL && !memcmp(PHPDBG_G(ops)->filename, new_break->class_name, new_break->class_len)) {
- if (phpdbg_resolve_op_array_break(new_break, PHPDBG_G(ops) TSRMLS_CC) == SUCCESS) {
- return SUCCESS;
- } else {
- return 2;
- }
- }
- return FAILURE;
- } else {
- zend_execute_data *execute_data = EG(current_execute_data);
- do {
- if (execute_data->op_array->function_name == NULL && execute_data->op_array->scope == NULL && !memcmp(execute_data->op_array->filename, new_break->class_name, new_break->class_len)) {
- if (phpdbg_resolve_op_array_break(new_break, execute_data->op_array TSRMLS_CC) == SUCCESS) {
- return SUCCESS;
- } else {
- return 2;
- }
- }
- } while ((execute_data = execute_data->prev_execute_data) != NULL);
- return FAILURE;
- }
- }
- if (new_break->class_name != NULL) {
- zend_class_entry **ce;
- if (zend_hash_find(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len + 1, (void **)&ce) == FAILURE) {
- return FAILURE;
- }
- func_table = &(*ce)->function_table;
- }
- if (zend_hash_find(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len + 1, (void **)&func) == FAILURE) {
- if (new_break->class_name != NULL && new_break->func_name != NULL) {
- phpdbg_error("Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name);
- return 2;
- }
- return FAILURE;
- }
- if (func->type != ZEND_USER_FUNCTION) {
- if (new_break->class_name == NULL) {
- phpdbg_error("%s is not an user defined function, no oplines exist", new_break->func_name);
- } else {
- phpdbg_error("%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name);
- }
- return 2;
- }
- if (phpdbg_resolve_op_array_break(new_break, &func->op_array TSRMLS_CC) == FAILURE) {
- return 2;
- }
- return SUCCESS;
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const char *method, zend_ulong opline TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakopline_t new_break;
- HashTable class_breaks, *class_table;
- HashTable method_breaks, *method_table;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_METHOD_OPLINE);
- new_break.func_len = strlen(method);
- new_break.func_name = estrndup(method, new_break.func_len);
- new_break.class_len = strlen(class);
- new_break.class_name = estrndup(class, new_break.class_len);
- new_break.opline_num = opline;
- new_break.opline = 0;
- switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
- case FAILURE:
- phpdbg_notice("Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline);
- break;
- case SUCCESS:
- phpdbg_notice("Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline);
- break;
- case 2:
- return;
- }
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, (void **)&class_table) == FAILURE) {
- zend_hash_init(&class_breaks, 8, NULL, phpdbg_opline_class_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE],
- new_break.class_name,
- new_break.class_len,
- (void **)&class_breaks, sizeof(HashTable), (void **)&class_table);
- }
- if (zend_hash_find(class_table, new_break.func_name, new_break.func_len, (void **)&method_table) == FAILURE) {
- zend_hash_init(&method_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- class_table,
- new_break.func_name,
- new_break.func_len,
- (void **)&method_breaks, sizeof(HashTable), (void **)&method_table);
- }
- if (zend_hash_index_exists(method_table, opline)) {
- phpdbg_notice("Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline);
- efree((char*)new_break.func_name);
- efree((char*)new_break.class_name);
- PHPDBG_G(bp_count)--;
- return;
- }
- PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_OPLINE_BP;
- PHPDBG_BREAK_MAPPING(new_break.id, method_table);
- zend_hash_index_update(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
- }
- PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakopline_t new_break;
- HashTable func_breaks, *func_table;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FUNCTION_OPLINE);
- new_break.func_len = strlen(function);
- new_break.func_name = estrndup(function, new_break.func_len);
- new_break.class_len = 0;
- new_break.class_name = NULL;
- new_break.opline_num = opline;
- new_break.opline = 0;
- switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
- case FAILURE:
- phpdbg_notice("Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline);
- break;
- case SUCCESS:
- phpdbg_notice("Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline);
- break;
- case 2:
- return;
- }
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, (void **)&func_table) == FAILURE) {
- zend_hash_init(&func_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE],
- new_break.func_name,
- new_break.func_len,
- (void **)&func_breaks, sizeof(HashTable), (void **)&func_table);
- }
- if (zend_hash_index_exists(func_table, opline)) {
- phpdbg_notice("Breakpoint already exists for %s#%ld", new_break.func_name, opline);
- efree((char*)new_break.func_name);
- PHPDBG_G(bp_count)--;
- return;
- }
- PHPDBG_BREAK_MAPPING(new_break.id, func_table);
- PHPDBG_G(flags) |= PHPDBG_HAS_FUNCTION_OPLINE_BP;
- zend_hash_index_update(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
- }
- PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong opline TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakopline_t new_break;
- HashTable file_breaks, *file_table;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE_OPLINE);
- new_break.func_len = 0;
- new_break.func_name = NULL;
- new_break.class_len = strlen(file);
- new_break.class_name = estrndup(file, new_break.class_len);
- new_break.opline_num = opline;
- new_break.opline = 0;
- switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
- case FAILURE:
- phpdbg_notice("Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline);
- break;
- case SUCCESS:
- phpdbg_notice("Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline);
- break;
- case 2:
- return;
- }
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, (void **)&file_table) == FAILURE) {
- zend_hash_init(&file_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE],
- new_break.class_name,
- new_break.class_len,
- (void **)&file_breaks, sizeof(HashTable), (void **)&file_table);
- }
- if (zend_hash_index_exists(file_table, opline)) {
- phpdbg_notice("Breakpoint already exists for %s:%ld", new_break.class_name, opline);
- efree((char*)new_break.class_name);
- PHPDBG_G(bp_count)--;
- return;
- }
- PHPDBG_BREAK_MAPPING(new_break.id, file_table);
- PHPDBG_G(flags) |= PHPDBG_HAS_FILE_OPLINE_BP;
- zend_hash_index_update(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
- }
- PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakop_t new_break;
- zend_ulong hash = zend_hash_func(name, name_len);
- if (zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash)) {
- phpdbg_notice(
- "Breakpoint exists for %s", name);
- return;
- }
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPCODE);
- new_break.hash = hash;
- new_break.name = estrndup(name, name_len);
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash,
- &new_break, sizeof(phpdbg_breakop_t), NULL);
- PHPDBG_G(flags) |= PHPDBG_HAS_OPCODE_BP;
- phpdbg_notice("Breakpoint #%d added at %s", new_break.id, name);
- PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRMLS_DC) /* {{{ */
- {
- if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline)) {
- phpdbg_breakline_t new_break;
- PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE);
- new_break.opline = (zend_ulong) opline;
- new_break.base = NULL;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
- (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t), NULL);
- phpdbg_notice("Breakpoint #%d added at %#lx",
- new_break.id, new_break.opline);
- PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- }
- } /* }}} */
- static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, const phpdbg_param_t *param, const char *expr, size_t expr_len, zend_ulong hash TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakcond_t new_break;
- zend_uint cops = CG(compiler_options);
- zval pv;
- PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_COND);
- new_break.hash = hash;
- if (param) {
- new_break.paramed = 1;
- phpdbg_copy_param(
- param, &new_break.param TSRMLS_CC);
- } else {
- new_break.paramed = 0;
- }
- cops = CG(compiler_options);
- CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
- new_break.code = estrndup(expr, expr_len);
- new_break.code_len = expr_len;
- Z_STRLEN(pv) = expr_len + sizeof("return ;") - 1;
- Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1);
- memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
- memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, expr, expr_len);
- Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
- Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
- Z_TYPE(pv) = IS_STRING;
- new_break.ops = zend_compile_string(
- &pv, "Conditional Breakpoint Code" TSRMLS_CC);
- zval_dtor(&pv);
- if (new_break.ops) {
- zend_hash_index_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break,
- sizeof(phpdbg_breakcond_t), (void**)&brake);
- phpdbg_notice("Conditional breakpoint #%d added %s/%p",
- brake->id, brake->code, brake->ops);
- PHPDBG_G(flags) |= PHPDBG_HAS_COND_BP;
- PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
- } else {
- phpdbg_error(
- "Failed to compile code for expression %s", expr);
- efree((char*)new_break.code);
- PHPDBG_G(bp_count)--;
- }
- CG(compiler_options) = cops;
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_len TSRMLS_DC) /* {{{ */
- {
- zend_ulong expr_hash = zend_inline_hash_func(expr, expr_len);
- phpdbg_breakcond_t new_break;
- if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], expr_hash)) {
- phpdbg_create_conditional_break(
- &new_break, NULL, expr, expr_len, expr_hash TSRMLS_CC);
- } else {
- phpdbg_notice("Conditional break %s exists", expr);
- }
- } /* }}} */
- PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakcond_t new_break;
- phpdbg_param_t *condition;
- zend_ulong hash = 0L;
-
- if (param->next) {
- condition = param->next;
- hash = zend_inline_hash_func(condition->str, condition->len);
-
- if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash)) {
- phpdbg_create_conditional_break(
- &new_break, param,
- condition->str, condition->len, hash TSRMLS_CC);
- } else {
- phpdbg_notice(
- "Conditional break %s exists at the specified location", condition->str);
- }
- }
-
- } /* }}} */
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */
- {
- HashTable *breaks;
- phpdbg_breakbase_t *brake;
- size_t name_len = strlen(op_array->filename);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename,
- name_len, (void**)&breaks) == FAILURE) {
- return NULL;
- }
- if (zend_hash_index_find(breaks, (*EG(opline_ptr))->lineno, (void**)&brake) == SUCCESS) {
- return brake;
- }
- return NULL;
- } /* }}} */
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */
- {
- const char *fname;
- zend_op_array *ops;
- phpdbg_breakbase_t *brake;
- if (fbc->type != ZEND_USER_FUNCTION) {
- return NULL;
- }
- ops = (zend_op_array*)fbc;
- if (ops->scope) {
- /* find method breaks here */
- return phpdbg_find_breakpoint_method(ops TSRMLS_CC);
- }
- fname = ops->function_name;
- if (!fname) {
- fname = "main";
- }
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, strlen(fname), (void**)&brake) == SUCCESS) {
- return brake;
- }
- return NULL;
- } /* }}} */
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_method(zend_op_array *ops TSRMLS_DC) /* {{{ */
- {
- HashTable *class_table;
- phpdbg_breakbase_t *brake;
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name,
- ops->scope->name_length, (void**)&class_table) == SUCCESS) {
- char *lcname = zend_str_tolower_dup(ops->function_name, strlen(ops->function_name));
- size_t lcname_len = strlen(lcname);
- if (zend_hash_find(
- class_table,
- lcname,
- lcname_len, (void**)&brake) == SUCCESS) {
- efree(lcname);
- return brake;
- }
- efree(lcname);
- }
- return NULL;
- } /* }}} */
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opline(phpdbg_opline_ptr_t opline TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakline_t *brake;
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
- (zend_ulong) opline, (void**)&brake) == SUCCESS) {
- return (brake->base?(phpdbg_breakbase_t *)brake->base:(phpdbg_breakbase_t *)brake);
- }
- return NULL;
- } /* }}} */
- static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opcode(zend_uchar opcode TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakbase_t *brake;
- const char *opname = phpdbg_decode_opcode(opcode);
- if (memcmp(opname, PHPDBG_STRL("UNKNOWN")) == 0) {
- return NULL;
- }
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE],
- zend_hash_func(opname, strlen(opname)), (void**)&brake) == SUCCESS) {
- return brake;
- }
- return NULL;
- } /* }}} */
- static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
- {
- zend_function *function = (zend_function*) execute_data->function_state.function;
- switch (param->type) {
- case NUMERIC_FUNCTION_PARAM:
- case STR_PARAM: {
- /* function breakpoint */
- if (function->type != ZEND_USER_FUNCTION) {
- return 0;
- }
- {
- const char *str = NULL;
- size_t len = 0L;
- zend_op_array *ops = (zend_op_array*)function;
- str = ops->function_name ? ops->function_name : "main";
- len = strlen(str);
- if (len == param->len && memcmp(param->str, str, len) == SUCCESS) {
- return param->type == STR_PARAM || execute_data->opline - ops->opcodes == param->num;
- }
- }
- } break;
- case FILE_PARAM: {
- if (param->file.line == zend_get_executed_lineno(TSRMLS_C)) {
- const char *str = zend_get_executed_filename(TSRMLS_C);
- size_t lengths[2] = {strlen(param->file.name), strlen(str)};
- if (lengths[0] == lengths[1]) {
- return (memcmp(
- param->file.name, str, lengths[0]) == SUCCESS);
- }
- }
- } break;
- case NUMERIC_METHOD_PARAM:
- case METHOD_PARAM: {
- if (function->type != ZEND_USER_FUNCTION) {
- return 0;
- }
- {
- zend_op_array *ops = (zend_op_array*) function;
- if (ops->scope) {
- size_t lengths[2] = {strlen(param->method.class), ops->scope->name_length};
- if (lengths[0] == lengths[1] && memcmp(param->method.class, ops->scope->name, lengths[0]) == SUCCESS) {
- lengths[0] = strlen(param->method.name);
- lengths[1] = strlen(ops->function_name);
- if (lengths[0] == lengths[1] && memcmp(param->method.name, ops->function_name, lengths[0]) == SUCCESS) {
- return param->type == METHOD_PARAM || (execute_data->opline - ops->opcodes) == param->num;
- }
- }
- }
- }
- } break;
- case ADDR_PARAM: {
- return ((zend_ulong)(phpdbg_opline_ptr_t)execute_data->opline == param->addr);
- } break;
- default: {
- /* do nothing */
- } break;
- }
- return 0;
- } /* }}} */
- static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakcond_t *bp;
- HashPosition position;
- int breakpoint = FAILURE;
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void*)&bp, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
- zval *retval = NULL;
- int orig_interactive = CG(interactive);
- zval **orig_retval = EG(return_value_ptr_ptr);
- zend_op_array *orig_ops = EG(active_op_array);
- zend_op **orig_opline = EG(opline_ptr);
- if (((phpdbg_breakbase_t*)bp)->disabled) {
- continue;
- }
- if (bp->paramed) {
- if (!phpdbg_find_breakpoint_param(&bp->param, execute_data TSRMLS_CC)) {
- continue;
- }
- }
- ALLOC_INIT_ZVAL(retval);
- EG(return_value_ptr_ptr) = &retval;
- EG(active_op_array) = bp->ops;
- EG(no_extensions) = 1;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- CG(interactive) = 0;
- zend_try {
- PHPDBG_G(flags) |= PHPDBG_IN_COND_BP;
- zend_execute(EG(active_op_array) TSRMLS_CC);
- #if PHP_VERSION_ID >= 50700
- if (zend_is_true(retval TSRMLS_CC)) {
- #else
- if (zend_is_true(retval)) {
- #endif
- breakpoint = SUCCESS;
- }
- } zend_catch {
- CG(interactive) = orig_interactive;
- EG(no_extensions)=1;
- EG(return_value_ptr_ptr) = orig_retval;
- EG(active_op_array) = orig_ops;
- EG(opline_ptr) = orig_opline;
- PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
- } zend_end_try();
- CG(interactive) = orig_interactive;
- EG(no_extensions)=1;
- EG(return_value_ptr_ptr) = orig_retval;
- EG(active_op_array) = orig_ops;
- EG(opline_ptr) = orig_opline;
- PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
- if (breakpoint == SUCCESS) {
- break;
- }
- }
- return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t*)bp) : NULL;
- } /* }}} */
- PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute_data TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakbase_t *base = NULL;
- if (!(PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED)) {
- return NULL;
- }
- /* conditions cannot be executed by eval()'d code */
- if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL) &&
- (PHPDBG_G(flags) & PHPDBG_HAS_COND_BP) &&
- (base = phpdbg_find_conditional_breakpoint(execute_data TSRMLS_CC))) {
- goto result;
- }
- if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) &&
- (base = phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC))) {
- goto result;
- }
- if (PHPDBG_G(flags) & (PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_SYM_BP)) {
- /* check we are at the beginning of the stack */
- if (execute_data->opline == EG(active_op_array)->opcodes) {
- if ((base = phpdbg_find_breakpoint_symbol(
- execute_data->function_state.function TSRMLS_CC))) {
- goto result;
- }
- }
- }
- if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) &&
- (base = phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC))) {
- goto result;
- }
- if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) &&
- (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) {
- goto result;
- }
- return NULL;
- result:
- /* we return nothing for disable breakpoints */
- if (base->disabled) {
- return NULL;
- }
- return base;
- } /* }}} */
- PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
- {
- HashTable **table;
- HashPosition position;
- phpdbg_breakbase_t *brake;
- if ((brake = phpdbg_find_breakbase_ex(num, &table, &position TSRMLS_CC))) {
- char *key;
- zend_uint klen;
- zend_ulong idx;
- int type = brake->type;
- char *name = NULL;
- size_t name_len = 0L;
- switch (type) {
- case PHPDBG_BREAK_FILE:
- case PHPDBG_BREAK_METHOD:
- if (zend_hash_num_elements((*table)) == 1) {
- name = estrdup(brake->name);
- name_len = strlen(name);
- if (zend_hash_num_elements(&PHPDBG_G(bp)[type]) == 1) {
- PHPDBG_G(flags) &= ~(1<<(brake->type+1));
- }
- }
- break;
- default: {
- if (zend_hash_num_elements((*table)) == 1) {
- PHPDBG_G(flags) &= ~(1<<(brake->type+1));
- }
- }
- }
- switch (type) {
- case PHPDBG_BREAK_FILE_OPLINE:
- case PHPDBG_BREAK_FUNCTION_OPLINE:
- case PHPDBG_BREAK_METHOD_OPLINE:
- if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]) == 1) {
- PHPDBG_G(flags) &= PHPDBG_HAS_OPLINE_BP;
- }
- zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t*)brake)->opline);
- }
- switch (zend_hash_get_current_key_ex(
- (*table), &key, &klen, &idx, 0, &position)) {
- case HASH_KEY_IS_STRING:
- zend_hash_del((*table), key, klen);
- break;
- default:
- zend_hash_index_del((*table), idx);
- }
- switch (type) {
- case PHPDBG_BREAK_FILE:
- case PHPDBG_BREAK_METHOD:
- if (name) {
- zend_hash_del(&PHPDBG_G(bp)[type], name, name_len);
- efree(name);
- }
- break;
- }
- phpdbg_notice("Deleted breakpoint #%ld", num);
- PHPDBG_BREAK_UNMAPPING(num);
- } else {
- phpdbg_error("Failed to find breakpoint #%ld", num);
- }
- } /* }}} */
- PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D) /* {{{ */
- {
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
- zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]);
- PHPDBG_G(flags) &= ~PHPDBG_BP_MASK;
- PHPDBG_G(bp_count) = 0;
- } /* }}} */
- PHPDBG_API void phpdbg_hit_breakpoint(phpdbg_breakbase_t *brake, zend_bool output TSRMLS_DC) /* {{{ */
- {
- brake->hits++;
- if (output) {
- phpdbg_print_breakpoint(brake TSRMLS_CC);
- }
- } /* }}} */
- PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* {{{ */
- {
- if (!brake)
- goto unknown;
- switch (brake->type) {
- case PHPDBG_BREAK_FILE: {
- phpdbg_notice("Breakpoint #%d at %s:%ld, hits: %lu",
- ((phpdbg_breakfile_t*)brake)->id,
- ((phpdbg_breakfile_t*)brake)->filename,
- ((phpdbg_breakfile_t*)brake)->line,
- ((phpdbg_breakfile_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_SYM: {
- phpdbg_notice("Breakpoint #%d in %s() at %s:%u, hits: %lu",
- ((phpdbg_breaksymbol_t*)brake)->id,
- ((phpdbg_breaksymbol_t*)brake)->symbol,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakfile_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %#lx at %s:%u, hits: %lu",
- ((phpdbg_breakline_t*)brake)->id,
- ((phpdbg_breakline_t*)brake)->opline,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakline_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_METHOD_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu",
- ((phpdbg_breakopline_t*)brake)->id,
- ((phpdbg_breakopline_t*)brake)->class_name,
- ((phpdbg_breakopline_t*)brake)->func_name,
- ((phpdbg_breakopline_t*)brake)->opline_num,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakopline_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_FUNCTION_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu",
- ((phpdbg_breakopline_t*)brake)->id,
- ((phpdbg_breakopline_t*)brake)->func_name,
- ((phpdbg_breakopline_t*)brake)->opline_num,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakopline_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_FILE_OPLINE: {
- phpdbg_notice("Breakpoint #%d in %s:%lu at %s:%u, hits: %lu",
- ((phpdbg_breakopline_t*)brake)->id,
- ((phpdbg_breakopline_t*)brake)->class_name,
- ((phpdbg_breakopline_t*)brake)->opline_num,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakopline_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_OPCODE: {
- phpdbg_notice("Breakpoint #%d in %s at %s:%u, hits: %lu",
- ((phpdbg_breakop_t*)brake)->id,
- ((phpdbg_breakop_t*)brake)->name,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakop_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_METHOD: {
- phpdbg_notice("Breakpoint #%d in %s::%s() at %s:%u, hits: %lu",
- ((phpdbg_breakmethod_t*)brake)->id,
- ((phpdbg_breakmethod_t*)brake)->class_name,
- ((phpdbg_breakmethod_t*)brake)->func_name,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakmethod_t*)brake)->hits);
- } break;
- case PHPDBG_BREAK_COND: {
- if (((phpdbg_breakcond_t*)brake)->paramed) {
- char *param;
- phpdbg_notice("Conditional breakpoint #%d: at %s if %s %s:%u, hits: %lu",
- ((phpdbg_breakcond_t*)brake)->id,
- phpdbg_param_tostring(&((phpdbg_breakcond_t*)brake)->param, ¶m TSRMLS_CC),
- ((phpdbg_breakcond_t*)brake)->code,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakcond_t*)brake)->hits);
- if (param)
- free(param);
- } else {
- phpdbg_notice("Conditional breakpoint #%d: on %s == true %s:%u, hits: %lu",
- ((phpdbg_breakcond_t*)brake)->id,
- ((phpdbg_breakcond_t*)brake)->code,
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C),
- ((phpdbg_breakcond_t*)brake)->hits);
- }
- } break;
- default: {
- unknown:
- phpdbg_notice("Unknown breakpoint at %s:%u",
- zend_get_executed_filename(TSRMLS_C),
- zend_get_executed_lineno(TSRMLS_C));
- }
- }
- } /* }}} */
- PHPDBG_API void phpdbg_enable_breakpoint(zend_ulong id TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakbase_t *brake = phpdbg_find_breakbase(id TSRMLS_CC);
- if (brake) {
- brake->disabled = 0;
- }
- } /* }}} */
- PHPDBG_API void phpdbg_disable_breakpoint(zend_ulong id TSRMLS_DC) /* {{{ */
- {
- phpdbg_breakbase_t *brake = phpdbg_find_breakbase(id TSRMLS_CC);
- if (brake) {
- brake->disabled = 1;
- }
- } /* }}} */
- PHPDBG_API void phpdbg_enable_breakpoints(TSRMLS_D) /* {{{ */
- {
- PHPDBG_G(flags) |= PHPDBG_IS_BP_ENABLED;
- } /* }}} */
- PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D) { /* {{{ */
- PHPDBG_G(flags) &= ~PHPDBG_IS_BP_ENABLED;
- } /* }}} */
- PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC) /* {{{ */
- {
- HashTable **table;
- HashPosition position;
- return phpdbg_find_breakbase_ex(id, &table, &position TSRMLS_CC);
- } /* }}} */
- PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC) /* {{{ */
- {
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, (void**)table) == SUCCESS) {
- phpdbg_breakbase_t *brake;
- for (zend_hash_internal_pointer_reset_ex((**table), position);
- zend_hash_get_current_data_ex((**table), (void**)&brake, position) == SUCCESS;
- zend_hash_move_forward_ex((**table), position)) {
- if (brake->id == id) {
- return brake;
- }
- }
- }
- return NULL;
- } /* }}} */
- PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */
- {
- switch (type) {
- case PHPDBG_BREAK_SYM: if ((PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP)) {
- HashPosition position;
- phpdbg_breaksymbol_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Function Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position)) {
- phpdbg_writeln("#%d\t\t%s%s",
- brake->id, brake->symbol,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- } break;
- case PHPDBG_BREAK_METHOD: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_BP)) {
- HashPosition position[2];
- HashTable *class_table;
- char *class_name = NULL;
- zend_uint class_len = 0;
- zend_ulong class_idx = 0L;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Method Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) {
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
- &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
- phpdbg_breakmethod_t *brake;
- for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]);
- zend_hash_get_current_data_ex(class_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(class_table, &position[1])) {
- phpdbg_writeln("#%d\t\t%s::%s%s",
- brake->id, brake->class_name, brake->func_name,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
- } break;
- case PHPDBG_BREAK_FILE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP)) {
- HashPosition position[2];
- HashTable *points;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("File Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) {
- phpdbg_breakfile_t *brake;
- for (zend_hash_internal_pointer_reset_ex(points, &position[1]);
- zend_hash_get_current_data_ex(points, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(points, &position[1])) {
- phpdbg_writeln("#%d\t\t%s:%lu%s",
- brake->id, brake->filename, brake->line,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- } break;
- case PHPDBG_BREAK_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)) {
- HashPosition position;
- phpdbg_breakline_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) {
- switch (brake->type) {
- case PHPDBG_BREAK_METHOD_OPLINE:
- case PHPDBG_BREAK_FUNCTION_OPLINE:
- case PHPDBG_BREAK_FILE_OPLINE:
- phpdbg_writeln("#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline,
- brake->type == PHPDBG_BREAK_METHOD_OPLINE?"method":
- brake->type == PHPDBG_BREAK_FUNCTION_OPLINE?"function":
- brake->type == PHPDBG_BREAK_FILE_OPLINE?"file":
- "--- error ---",
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
- default:
- phpdbg_writeln("#%d\t\t%#lx", brake->id, brake->opline);
- break;
- }
- }
- } break;
- case PHPDBG_BREAK_METHOD_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP)) {
- HashPosition position[3];
- HashTable *class_table, *method_table;
- char *class_name = NULL, *method_name = NULL;
- zend_uint class_len = 0, method_len = 0;
- zend_ulong class_idx = 0L, method_idx = 0L;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Method opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) {
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE],
- &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
- for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]);
- zend_hash_get_current_data_ex(class_table, (void**) &method_table, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(class_table, &position[1])) {
- if (zend_hash_get_current_key_ex(class_table,
- &method_name, &method_len, &method_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
- phpdbg_breakopline_t *brake;
- for (zend_hash_internal_pointer_reset_ex(method_table, &position[2]);
- zend_hash_get_current_data_ex(method_table, (void**)&brake, &position[2]) == SUCCESS;
- zend_hash_move_forward_ex(method_table, &position[2])) {
- phpdbg_writeln("#%d\t\t%s::%s opline %ld%s",
- brake->id, brake->class_name, brake->func_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
- }
- }
- } break;
- case PHPDBG_BREAK_FUNCTION_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP)) {
- HashPosition position[2];
- HashTable *function_table;
- char *function_name = NULL;
- zend_uint function_len = 0;
- zend_ulong function_idx = 0L;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Function opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) {
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE],
- &function_name, &function_len, &function_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
- phpdbg_breakopline_t *brake;
- for (zend_hash_internal_pointer_reset_ex(function_table, &position[1]);
- zend_hash_get_current_data_ex(function_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(function_table, &position[1])) {
- phpdbg_writeln("#%d\t\t%s opline %ld%s",
- brake->id, brake->func_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
- } break;
- case PHPDBG_BREAK_FILE_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP)) {
- HashPosition position[2];
- HashTable *file_table;
- char *file_name = NULL;
- zend_uint file_len = 0;
- zend_ulong file_idx = 0L;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("File opline Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) {
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE],
- &file_name, &file_len, &file_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
- phpdbg_breakopline_t *brake;
- for (zend_hash_internal_pointer_reset_ex(file_table, &position[1]);
- zend_hash_get_current_data_ex(file_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(file_table, &position[1])) {
- phpdbg_writeln("#%d\t\t%s opline %ld%s",
- brake->id, brake->class_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
- } break;
- case PHPDBG_BREAK_COND: if ((PHPDBG_G(flags) & PHPDBG_HAS_COND_BP)) {
- HashPosition position;
- phpdbg_breakcond_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Conditional Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
- if (brake->paramed) {
- switch (brake->param.type) {
- case STR_PARAM:
- phpdbg_writeln("#%d\t\tat %s if %s%s",
- brake->id,
- brake->param.str,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
- case NUMERIC_FUNCTION_PARAM:
- phpdbg_writeln("#%d\t\tat %s#%ld if %s%s",
- brake->id,
- brake->param.str,
- brake->param.num,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
- case METHOD_PARAM:
- phpdbg_writeln("#%d\t\tat %s::%s if %s%s",
- brake->id,
- brake->param.method.class,
- brake->param.method.name,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
- case NUMERIC_METHOD_PARAM:
- phpdbg_writeln("#%d\t\tat %s::%s#%ld if %s%s",
- brake->id,
- brake->param.method.class,
- brake->param.method.name,
- brake->param.num,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
- case FILE_PARAM:
- phpdbg_writeln("#%d\t\tat %s:%lu if %s%s",
- brake->id,
- brake->param.file.name,
- brake->param.file.line,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
- case ADDR_PARAM:
- phpdbg_writeln("#%d\t\tat #%lx if %s%s",
- brake->id,
- brake->param.addr,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
- default:
- phpdbg_error("Invalid parameter type for conditional breakpoint");
- return;
- }
- } else {
- phpdbg_writeln("#%d\t\tif %s%s",
- brake->id, brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- } break;
- case PHPDBG_BREAK_OPCODE: if (PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) {
- HashPosition position;
- phpdbg_breakop_t *brake;
- phpdbg_writeln(SEPARATE);
- phpdbg_writeln("Opcode Breakpoints:");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) {
- phpdbg_writeln("#%d\t\t%s%s",
- brake->id, brake->name,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- } break;
- }
- } /* }}} */
|