int pmem_free(void *ptr, size_t size, int fd) { int err, ret = 0; size_t aligned_size = align_size(size); pmem_region region = { 0, aligned_size }; err = ioctl(fd, PMEM_UNMAP, ®ion); if (IOCTL_FAILED == err) { LOGE("PMEM_UNMAP size %d failed!", size); ret = err; } err = munmap(ptr, aligned_size); if (UNMAP_FAILED == err) { LOGE("mumap size %d failed!", size); ret = err; } err = close(fd); if (CLOSE_FAILED == err) { LOGE("Close file %d failed!", fd); ret = err; } property_get("pm.dumpstack", p_value, "0"); //if not set, disable by default p_res = atoi(p_value); if (p_res) { LOGE("[PMEM] pmem_free: base: 0x%08x, size: %d\n", (int)ptr, aligned_size); dump_stack_trace(); } return ret; }
int main(int argc, char **argv) { if (argc == 1) { fprintf(stderr, "You need to supply a binary as an argument e.g ./zdb <bin>"); exit(-1); } const char *path = argv[1]; const char *name = strrchr(path, '/'); if (name) { name += 1; } else { name = path; } pid_t pid; switch(pid = fork()) { // error case -1: { perror("fork()"); exit(-1); } // this is our child case 0: { ptrace(PTRACE_TRACEME, 1337, NULL); execl(path, name, NULL); perror("execl()"); exit(-1); } } int status; long opcode[4]; long previous_ip; wait(&status); while(1) { if(WIFEXITED(status) || (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)) { printf("terminated"); exit(0); } if(WIFSTOPPED(status)) { long rip = ptrace(PTRACE_PEEKUSER, pid, 8 * RIP, NULL)-1; printf("Instruction stopped at: 0x%lx\n", rip); } /* read our user's command in */ zdb_command command = next_command(); switch(command.instruction) { case NEXT: { long ip = ptrace(PTRACE_PEEKUSER, pid, 8 * RIP, NULL); if(previous_ip) { long opcode_len = ip - previous_ip; if(opcode_len > 0 && opcode_len < 16) print_instruction(&opcode, opcode_len); } opcode[0] = ptrace(PTRACE_PEEKDATA, pid, ip, NULL); opcode[1] = ptrace(PTRACE_PEEKDATA, pid, ip + sizeof(long), NULL); previous_ip = ip; ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL); wait(&status); break; } case DUMP: dump_registers(pid); break; case HEXDUMP: { long addr; unsigned int size; sscanf(command.args, "%lx %u", &addr, &size); hexdump_region(addr, size, pid, true); break; } case STACK_TRACE: dump_stack_trace(pid); break; case QUIT: { printf("quitting zdb"); exit(0); } default: fprintf(stderr, "invalid or unknown command\n"); } } }