1.使用gdb调试
* /proc/kcore文件是系统内核运行情况的内存映像
* 如果编译内核的时候增加-g选项,即会在生成的二进制代码vmlinuz或vmlinux中,添加调试相关的数据。
* 以root身份运行
#gdb /usr/src/linux/vmlinux /proc/kcore
* 因为core-file命令是静态的,如果需要查看内核最近的运行情况,需要再次运行core-file将新的/proc/kcore导入,否则就只能是上次使用core-file的情况
# gdb vmlinux
# (gdb) core-file /proc/kcore
# #0 0x0 in ?? ()
# (gdb) p jiffies
# $1 = 29119787
# (gdb) p jiffies
# $2 = 29119787
# (gdb) core-file /proc/kcore
# #0 0x0 in ?? ()
# (gdb) p jiffies
# $3 = 29122291
# (gdb)
2.Core Dump
1>开启系统的Core Dump功能
ulimit -c core_file_size_in_kb
如果要关闭该功能core_file_size_in_kb为0就行了。
ulimit -c 1000
2>设置Core Dump的核心转储文件目录和命名规则
文件的命名规则放在
/proc/sys/kernel/core_name_format文件中
使用sysctl -w "kernel.core_name_format=/coredump/%n.core"
上例的core文件放在/coredump目录下,文件名是进程名+.core
以下是一些命名的格式说明
%P The Process ID (current->pid)
%U The UID of the process (current->uid)
%N The command name of the process (current->comm)
%H The nodename of the system (system_utsname.nodename)
%% A "%"
3.UML调试内核
1>直接使用gdb运行UML内核
root@wangyao-desktop:/usr/src/linux-2.6.24#
gdb -q ./linux ubd0=/uml/Debian-4.0-x86-root_fs mem=128M
eth0=tuntap,,,192.168.1.11 umid=ubuntu
Excess command line arguments ignored. (mem=128M ...)
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
/usr/src/linux-2.6.24/ubd0=/uml/Debian-4.0-x86-root_fs: No such file or directory.
(gdb) b start_kernel
Breakpoint 1 at 0x80493a7: file init/main.c, line 512.
(gdb) r
Starting program: /usr/src/linux-2.6.24/linux
Core dump limits :
soft - 0
hard - NONE
Checking that ptrace can change system call numbers...OK
Checking syscall emulation patch for ptrace...OK
Checking advanced syscall emulation patch for ptrace...OK
Checking for tmpfs mount on /dev/shm...OK
Checking PROT_EXEC mmap in /dev/shm/...OK
Checking for the skas3 patch in the host:
- /proc/mm...not found: No such file or directory
- PTRACE_FAULTINFO...not found
- PTRACE_LDT...not found
UML running in SKAS0 mode
Breakpoint 1, start_kernel () at init/main.c:512
512 smp_setup_processor_id();
2>先运行了UML内核,再通过gdb attach到相应的进程
root@wangyao-desktop:/usr/src/linux-2.6.24# cat ~/.uml/ubuntu/pid
13678
root@wangyao-desktop:/usr/src/linux-2.6.24# gdb -q ./linux 13678
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
Attaching to program: /usr/src/linux-2.6.24/linux, process 13678
Reading symbols from /lib/tls/i686/cmov/libutil.so.1...done.
Loaded symbols for /lib/tls/i686/cmov/libutil.so.1
Reading symbols from /lib/tls/i686/cmov/libc.so.6...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
0xffffe410 in __kernel_vsyscall ()
(gdb) b do_execve
Breakpoint 1 at 0x80b0491: file fs/exec.c, line 1303.
(gdb) c
Continuing.
3> 调试module
UML# modprobe loop
UML# lsmod
Module Size Used by
loop 12328 0
gdb中调试:
(gdb) p modules
$6 = {next = 0x108030a4, prev = 0x1082a084}
The
"next" address is 4 bytes (on x86, 8 on x86_64) into the module
structure, so you can print the structure by subtracting that from the
address in the modules list_head:
(gdb) p *((struct module *)0x108030a0)
$7
= {state = MODULE_STATE_LIVE, list = {next = 0x1082a084, prev =
0x8206c2c}, name = "loop", '\0' , mkobj = {kobj
= {k_name = 0xfed7fa0 "loop", kref = {
refcount = {counter =
4}}, entry = {next = 0x8203884, prev = 0x1082a0d0}, parent = 0x820388c,
kset = 0x8203880, ktype = 0x0, sd = 0xfe2d9f8}, mod = 0x108030a0,
drivers_dir = 0x0}, param_attrs = 0x0, modinfo_attrs = 0xfedaf08,
version = 0x0, srcversion = 0x0, holders_dir = 0xfed7868, syms =
0x10801d20, num_syms = 2, crcs = 0x0,
gpl_syms = 0x0,
num_gpl_syms = 0, gpl_crcs = 0x0, unused_syms = 0x0, num_unused_syms =
0, unused_crcs = 0x0, unused_gpl_syms = 0x0, num_unused_gpl_syms = 0,
unused_gpl_crcs = 0x0, gpl_future_syms = 0x0, num_gpl_future_syms = 0,
gpl_future_crcs = 0x0, num_exentries = 0, extable = 0x0, init =
0x10805000, module_init = 0x0,
module_core = 0x10800000,
init_size = 0, core_size = 12808, init_text_size = 0, core_text_size =
6909, unwind_info = 0x0, arch = {}, taints = 0,
bug_list = {
next = 0x1082a16c, prev = 0x8209d28}, bug_table =
0x0, num_bugs = 0, ref = {{count = {a = {counter = 0}}}},
modules_which_use_me = {next = 0x108031c0, prev = 0x108031c0},
waiter = 0xfd1f040, exit = 0x10801a94, symtab = 0x10801d30, num_symtab
= 164, strtab = 0x10802770 "", sect_attrs = 0xfdf68d0, notes_attrs =
0xfe0b5a8, percpu = 0x0,
args = 0xfed76e0 ""}
# Once you
find the module structure you're interested in, look at the
"module_core" field (0x3502a000 above). Use that as ADDR in this
command:
(gdb) add-symbol-file HOST_PATH_TO_KO ADDR
For example, here that command looks like this
(gdb) obj/mods/lib/modules/2.6.18-rc3-mm2/kernel/drivers/block/loop.ko 0x3502a000
To verify that you have done this correctly, you can look at the init function address and see that gdb agrees about its address
(gdb) p loop_init
$5 = {int (void)} 0x3502a000
Now, you can set breakpoints and debug the module.
(gdb) b loop_init
Breakpoint 1 at 0x3502a009: file /home/jdike/linux/2.6/linux-2.6.18-mm/drivers/block/loop.c, line 1242.
(gdb) c
Continuing.
Breakpoint 1, loop_init ()
at /home/jdike/linux/2.6/linux-2.6.18-mm/drivers/block/loop.c:1242
1242 if (max_loop < 1 || max_loop > 256) {
(gdb)
阅读(756) | 评论(0) | 转发(0) |