static inline void phpdbg_print_function_helper(zend_function *method) /* {{{ */ { switch (method->type) { case ZEND_USER_FUNCTION: { zend_op_array* op_array = &(method->op_array); HashTable vars; if (op_array) { zend_op *opline = &(op_array->opcodes[0]); uint32_t opcode = 0, end = op_array->last-1; if (method->common.scope) { phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s", op_array->line_start, op_array->line_end, method->common.scope->name->val, method->common.function_name->val, op_array->filename ? op_array->filename->val : "unknown"); } else { phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s", method->common.function_name ? op_array->line_start : 0, method->common.function_name ? op_array->line_end : 0, method->common.function_name ? method->common.function_name->val : "{main}", op_array->filename ? op_array->filename->val : "unknown"); } zend_hash_init(&vars, op_array->last, NULL, NULL, 0); do { char *decode = phpdbg_decode_opline(op_array, opline, &vars); if (decode != NULL) { phpdbg_writeln("print", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\"", "\t\tL%u\t%p %-30s %s", opline->lineno, opline, phpdbg_decode_opcode(opline->opcode), decode); free(decode); } else { phpdbg_error("print", "type=\"decodefailure\" opline=\"%16p\"", "\tFailed to decode opline %16p", opline); } opline++; } while (opcode++ < end); zend_hash_destroy(&vars); } } break; default: { if (method->common.scope) { phpdbg_writeln("printoplineinfo", "type=\"Internal\" method=\"%s::%s\"", "\tInternal %s::%s()", method->common.scope->name->val, method->common.function_name->val); } else { phpdbg_writeln("printoplineinfo", "type=\"Internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name->val); } } } } /* }}} */
void phpdbg_list_file(const char *filename, long count, long offset TSRMLS_DC) /* {{{ */ { unsigned char *mem, *pos, *last_pos, *end_pos; struct stat st; #ifndef _WIN32 int fd; #else HANDLE fd, map; #endif int all_content = (count == 0); unsigned int line = 0, displayed = 0; if (VCWD_STAT(filename, &st) == -1) { phpdbg_error("Failed to stat file %s", filename); return; } #ifndef _WIN32 if ((fd = VCWD_OPEN(filename, O_RDONLY)) == -1) { phpdbg_error("Failed to open file %s to list", filename); return; } last_pos = mem = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); end_pos = mem + st.st_size; #else fd = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (fd == INVALID_HANDLE_VALUE) { phpdbg_error("Failed to open file!"); return; } map = CreateFileMapping(fd, NULL, PAGE_EXECUTE_READ, 0, 0, 0); if (map == NULL) { phpdbg_error("Failed to map file!"); CloseHandle(fd); return; } last_pos = mem = (char*) MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0); if (mem == NULL) { phpdbg_error("Failed to map file in memory"); CloseHandle(map); CloseHandle(fd); return; } end_pos = mem + st.st_size; #endif while (1) { pos = memchr(last_pos, '\n', end_pos - last_pos); if (!pos) { /* No more line breaks */ break; } ++line; if (!offset || offset <= line) { /* Without offset, or offset reached */ phpdbg_writeln("%05u: %.*s", line, (int)(pos - last_pos), last_pos); ++displayed; } last_pos = pos + 1; if (!all_content && displayed == count) { /* Reached max line to display */ break; } } #ifndef _WIN32 munmap(mem, st.st_size); close(fd); #else UnmapViewOfFile(mem); CloseHandle(map); CloseHandle(fd); #endif } /* }}} */