Better opcode dump for finally

* Move opcode decode into opline decode, so we can adjust it for
  extended_value.
* Show extended_value and secondary jump ops for FAST_CALL and
  FAST_RET.
This commit is contained in:
Nikita Popov 2015-07-10 11:22:34 +02:00
parent 95ff2852ee
commit bd72fdca98
2 changed files with 39 additions and 13 deletions

View file

@ -51,7 +51,24 @@ static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t
char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */
{ {
char *decode[4] = {NULL, NULL, NULL, NULL}; const char *opcode_name = phpdbg_decode_opcode(op->opcode);
char *result, *decode[4] = {NULL, NULL, NULL, NULL};
/* EX */
switch (op->opcode) {
case ZEND_FAST_CALL:
if (op->extended_value != 0) {
asprintf(&decode[0], "FAST_CALL<%s>",
op->extended_value == ZEND_FAST_CALL_FROM_CATCH ? "FROM_CATCH" : "FROM_FINALLY");
}
break;
case ZEND_FAST_RET:
if (op->extended_value != 0) {
asprintf(&decode[0], "FAST_RET<%s>",
op->extended_value == ZEND_FAST_RET_TO_CATCH ? "TO_CATCH" : "TO_FINALLY");
}
break;
}
/* OP1 */ /* OP1 */
switch (op->opcode) { switch (op->opcode) {
@ -74,9 +91,8 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */
/* OP2 */ /* OP2 */
switch (op->opcode) { switch (op->opcode) {
/* TODO: ZEND_FAST_CALL, ZEND_FAST_RET op2 */
case ZEND_JMPZNZ: case ZEND_JMPZNZ:
asprintf(&decode[2], "J%u or J%" PRIu32, OP_JMP_ADDR(op, op->op2) - ops->opcodes, ZEND_OFFSET_TO_OPLINE(op, op->extended_value) - ops->opcodes); asprintf(&decode[2], "J%ld or J%ld", OP_JMP_ADDR(op, op->op2) - ops->opcodes, ZEND_OFFSET_TO_OPLINE(op, op->extended_value) - ops->opcodes);
break; break;
case ZEND_JMPZ: case ZEND_JMPZ:
@ -88,6 +104,13 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */
asprintf(&decode[2], "J%ld", OP_JMP_ADDR(op, op->op2) - ops->opcodes); asprintf(&decode[2], "J%ld", OP_JMP_ADDR(op, op->op2) - ops->opcodes);
break; break;
case ZEND_FAST_CALL:
case ZEND_FAST_RET:
if (op->extended_value != 0) {
asprintf(&decode[2], "J%" PRIu32, op->op2.opline_num);
}
break;
case ZEND_SEND_VAL: case ZEND_SEND_VAL:
case ZEND_SEND_VAL_EX: case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR: case ZEND_SEND_VAR:
@ -113,12 +136,15 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */
break; break;
} }
asprintf(&decode[0], asprintf(&result,
"%-20s %-20s %-20s", "%-23s %-20s %-20s %-20s",
decode[0] ? decode[0] : opcode_name,
decode[1] ? decode[1] : "", decode[1] ? decode[1] : "",
decode[2] ? decode[2] : "", decode[2] ? decode[2] : "",
decode[3] ? decode[3] : ""); decode[3] ? decode[3] : "");
if (decode[0])
free(decode[0]);
if (decode[1]) if (decode[1])
free(decode[1]); free(decode[1]);
if (decode[2]) if (decode[2])
@ -126,7 +152,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */
if (decode[3]) if (decode[3])
free(decode[3]); free(decode[3]);
return decode[0]; return result;
} /* }}} */ } /* }}} */
void phpdbg_print_opline_ex(zend_execute_data *execute_data, zend_bool ignore_flags) /* {{{ */ void phpdbg_print_opline_ex(zend_execute_data *execute_data, zend_bool ignore_flags) /* {{{ */
@ -142,19 +168,17 @@ void phpdbg_print_opline_ex(zend_execute_data *execute_data, zend_bool ignore_fl
if (ignore_flags || (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || (PHPDBG_G(flags) & PHPDBG_IS_STEPPING))) { if (ignore_flags || (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || (PHPDBG_G(flags) & PHPDBG_IS_STEPPING))) {
/* output line info */ /* output line info */
phpdbg_notice("opline", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\" file=\"%s\"", "L%-5u %16p %-30s %s %s", phpdbg_notice("opline", "line=\"%u\" opline=\"%p\" op=\"%s\" file=\"%s\"", "L%-5u %16p %s %s",
opline->lineno, opline->lineno,
opline, opline,
phpdbg_decode_opcode(opline->opcode),
decode, decode,
execute_data->func->op_array.filename ? ZSTR_VAL(execute_data->func->op_array.filename) : "unknown"); execute_data->func->op_array.filename ? ZSTR_VAL(execute_data->func->op_array.filename) : "unknown");
} }
if (!ignore_flags && PHPDBG_G(oplog)) { if (!ignore_flags && PHPDBG_G(oplog)) {
phpdbg_log_ex(fileno(PHPDBG_G(oplog)), "L%-5u %16p %-30s %s %s", phpdbg_log_ex(fileno(PHPDBG_G(oplog)), "L%-5u %16p %s %s",
opline->lineno, opline->lineno,
opline, opline,
phpdbg_decode_opcode(opline->opcode),
decode, decode,
execute_data->func->op_array.filename ? ZSTR_VAL(execute_data->func->op_array.filename) : "unknown"); execute_data->func->op_array.filename ? ZSTR_VAL(execute_data->func->op_array.filename) : "unknown");
} }
@ -182,5 +206,8 @@ void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags
const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */
{ {
const char *ret = zend_get_opcode_name(opcode); const char *ret = zend_get_opcode_name(opcode);
return ret?ret:"UNKNOWN"; if (ret) {
return ret + 5; /* Skip ZEND_ prefix */
}
return "UNKNOWN";
} /* }}} */ } /* }}} */

View file

@ -83,10 +83,9 @@ static inline void phpdbg_print_function_helper(zend_function *method) /* {{{ */
do { do {
char *decode = phpdbg_decode_opline(op_array, opline); char *decode = phpdbg_decode_opline(op_array, opline);
if (decode != NULL) { if (decode != NULL) {
phpdbg_writeln("print", "line=\"%u\" opnum=\"%u\" opcode=\"%s\" op=\"%s\"", " L%-4u #%-5u %-23s %s", phpdbg_writeln("print", "line=\"%u\" opnum=\"%u\" op=\"%s\"", " L%-4u #%-5u %s",
opline->lineno, opline->lineno,
opcode, opcode,
phpdbg_decode_opcode(opline->opcode) + 5, /* remove ZEND_ prefix */
decode); decode);
free(decode); free(decode);
} else { } else {