dis === :: NAME dis - disassemble SYNOPSIS dis [-rfludxs][-b [num]] [address | symbol | (expression)] [count] DESCRIPTION This command disassembles source code instructions starting (or ending) at a text address that may be expressed by value, symbol or expression: -r (reverse) displays all instructions from the start of the routine up to and including the designated address. -f (forward) displays all instructions from the given address to the end of the routine. -l displays source code line number data in addition to the disassembly output. -u address is a user virtual address in the current context; otherwise the address is assumed to be a kernel virtual address. If this option is used, then -r and -l are ignored. -x override default output format with hexadecimal format. -d override default output format with decimal format. -s displays the filename and line number of the source code that is associated with the specified text location, followed by a source code listing if it is available on the host machine. The line associated with the text location will be marked with an asterisk; depending upon gdb's internal "listsize" variable, several lines will precede the marked location. If a "count" argument is entered, it specifies the number of source code lines to be displayed after the marked location; otherwise the remaining source code of the containing function will be displayed. -b [num] modify the pre-calculated number of encoded bytes to skip after a kernel BUG ("ud2a") instruction; with no argument, displays the current number of bytes being skipped. (x86 and x86_64 only) address starting hexadecimal text address. symbol symbol of starting text address. On ppc64, the symbol preceded by '.' is used. (expression) expression evaluating to a starting text address. count the number of instructions to be disassembled (default is 1). If no count argument is entered, and the starting address is entered as a text symbol, then the whole routine will be disassembled. The count argument is supported when used with the -r and -f options. EXAMPLES Disassemble the sys_signal() routine without, and then with, line numbers: crash> dis sys_signal 0xc0112c88 : push %ebp 0xc0112c89 : mov %esp,%ebp 0xc0112c8b : sub $0x28,%esp 0xc0112c8e : mov 0xc(%ebp),%eax 0xc0112c91 : mov %eax,0xffffffec(%ebp) 0xc0112c94 : movl $0xc0000000,0xfffffff0(%ebp) 0xc0112c9b : lea 0xffffffd8(%ebp),%eax 0xc0112c9e : push %eax 0xc0112c9f : lea 0xffffffec(%ebp),%eax 0xc0112ca2 : push %eax 0xc0112ca3 : pushl 0x8(%ebp) 0xc0112ca6 : call 0xc01124b8 0xc0112cab : test %eax,%eax 0xc0112cad : jne 0xc0112cb2 0xc0112caf : mov 0xffffffd8(%ebp),%eax 0xc0112cb2 : leave 0xc0112cb3 : ret crash> dis -l sys_signal /usr/src/linux-2.2.5/kernel/signal.c: 1074 0xc0112c88 : push %ebp 0xc0112c89 : mov %esp,%ebp 0xc0112c8b : sub $0x28,%esp 0xc0112c8e : mov 0xc(%ebp),%eax /usr/src/linux-2.2.5/kernel/signal.c: 1078 0xc0112c91 : mov %eax,0xffffffec(%ebp) /usr/src/linux-2.2.5/kernel/signal.c: 1079 0xc0112c94 : movl $0xc0000000,0xfffffff0(%ebp) /usr/src/linux-2.2.5/kernel/signal.c: 1081 0xc0112c9b : lea 0xffffffd8(%ebp),%eax 0xc0112c9e : push %eax 0xc0112c9f : lea 0xffffffec(%ebp),%eax 0xc0112ca2 : push %eax 0xc0112ca3 : pushl 0x8(%ebp) 0xc0112ca6 : call 0xc01124b8 /usr/src/linux-2.2.5/kernel/signal.c: 1083 0xc0112cab : test %eax,%eax 0xc0112cad : jne 0xc0112cb2 0xc0112caf : mov 0xffffffd8(%ebp),%eax /usr/src/linux-2.2.5/kernel/signal.c: 1084 0xc0112cb2 : leave 0xc0112cb3 : ret Given a return address expression of "do_no_page+65", find out the function that do_no_page() calls by using the reverse flag: crash> dis -r (do_no_page+65) 0xc011ea68 : push %ebp 0xc011ea69 : mov %esp,%ebp 0xc011ea6b : push %edi 0xc011ea6c : push %esi 0xc011ea6d : push %ebx 0xc011ea6e : mov 0xc(%ebp),%ebx 0xc011ea71 : mov 0x10(%ebp),%edx 0xc011ea74 : mov 0x14(%ebp),%edi 0xc011ea77 : mov 0x28(%ebx),%eax 0xc011ea7a : test %eax,%eax 0xc011ea7c : je 0xc011ea85 0xc011ea7e : mov 0x18(%eax),%ecx 0xc011ea81 : test %ecx,%ecx 0xc011ea83 : jne 0xc011eab0 0xc011ea85 : mov $0xffffe000,%eax 0xc011ea8a : and %esp,%eax 0xc011ea8c : decl 0x30(%eax) 0xc011ea8f : jns 0xc011ea9a 0xc011ea91 : lock btrl $0x0,0xc022fb60 0xc011ea9a : push %edi 0xc011ea9b : mov 0x18(%ebp),%esi 0xc011ea9e : push %esi 0xc011ea9f : push %ebx 0xc011eaa0 : mov 0x8(%ebp),%esi 0xc011eaa3 : push %esi 0xc011eaa4 : call 0xc011e9e4 0xc011eaa9 : jmp 0xc011eb47 Disassemble 10 instructions starting at user virtual address 0x81ec624: crash> dis -u 81ec624 10 0x81ec624: push %ebp 0x81ec625: mov %esp,%ebp 0x81ec627: sub $0x18,%esp 0x81ec62a: movl $0x1,0x8(%ebp) 0x81ec631: mov 0x82f9040,%eax 0x81ec636: mov 0x10(%eax),%edx 0x81ec639: and $0x100,%edx 0x81ec63f: mov 0x14(%eax),%ecx 0x81ec642: and $0x0,%ecx 0x81ec645: mov %ecx,%eax Override the current decimal output radix format: crash> dis sys_read 10 -x 0xffffffff8001178f : push %r13 0xffffffff80011791 : mov %rsi,%r13 0xffffffff80011794 : push %r12 0xffffffff80011796 : mov $0xfffffffffffffff7,%r12 0xffffffff8001179d : push %rbp 0xffffffff8001179e : mov %rdx,%rbp 0xffffffff800117a1 : push %rbx 0xffffffff800117a2 : sub $0x18,%rsp 0xffffffff800117a6 : lea 0x14(%rsp),%rsi 0xffffffff800117ab : callq 0xffffffff8000b5b4 Disassemble from vfs_read+320 until the end of the function: crash> dis -f vfs_read+320 0xffffffff8119d4e0 : cmpq $0x0,0x20(%rax) 0xffffffff8119d4e5 : jne 0xffffffff8119d3e8 0xffffffff8119d4eb : mov $0xffffffffffffffea,%r12 0xffffffff8119d4f2 : jmp 0xffffffff8119d4c3 0xffffffff8119d4f4 : nopl 0x0(%rax) 0xffffffff8119d4f8 : callq 0xffffffff8119cc40 0xffffffff8119d4fd : mov %rax,%r12 0xffffffff8119d500 : jmpq 0xffffffff8119d44c 0xffffffff8119d505 : nopl (%rax) 0xffffffff8119d508 : mov $0xfffffffffffffff7,%r12 0xffffffff8119d50f : jmp 0xffffffff8119d4c3 0xffffffff8119d511 : mov $0xfffffffffffffff2,%r12 0xffffffff8119d518 : jmp 0xffffffff8119d4c3 0xffffffff8119d51a : nopw 0x0(%rax,%rax,1) Display the source code listing of the mmput() function: crash> dis -s mmput FILE: kernel/fork.c LINE: 617 612 613 /* 614 * Decrement the use count and release all resources for an mm. 615 */ 616 void mmput(struct mm_struct *mm) * 617 { 618 might_sleep(); 619 620 if (atomic_dec_and_test(&mm->mm_users)) { 621 uprobe_clear_state(mm); 622 exit_aio(mm); 623 ksm_exit(mm); 624 khugepaged_exit(mm); /* must run before exit_mmap */ 625 exit_mmap(mm); 626 set_mm_exe_file(mm, NULL); 627 if (!list_empty(&mm->mmlist)) { 628 spin_lock(&mmlist_lock); 629 list_del(&mm->mmlist); 630 spin_unlock(&mmlist_lock); 631 } 632 if (mm->binfmt) 633 module_put(mm->binfmt->module); 634 mmdrop(mm); 635 } 636 } The disassembly of dentry_kill() shows an indirect call to a function whose address is contained within a register. Display the source code associated with the indirect function call: crash> dis dentry_kill ... 0xffffffff811dcfb4 : callq *%rax ... crash> dis -s 0xffffffff811dcfb4 FILE: fs/dcache.c LINE: 276 271 spin_unlock(&dentry->d_lock); 272 spin_unlock(&inode->i_lock); 273 if (!inode->i_nlink) 274 fsnotify_inoderemove(inode); 275 if (dentry->d_op && dentry->d_op->d_iput) * 276 dentry->d_op->d_iput(dentry, inode); 277 else 278 iput(inode); 279 } else { 280 spin_unlock(&dentry->d_lock); 281 } 282 }