(gdb) find_task 910

 Task 'syslogd':

or

(gdb) find_task 0xCFFDE470

 Task 'bash':

Line 4 defines the macro name. Line 7 decides whether the input argument is a PID (numeric entry starting at zero and limited to a few million) or a task_struct address that must be greater than the end of the Linux kernel image itself, defined by the symbol _end.[96] If it's an address, the only action required is to cast it to the proper type to enable dereferencing the associated task_struct. This is done at line 8. As the comment in line 3 states, this macro returns a gdb convenience variable typecasted to a pointer to a struct task_struct.

If the input argument is a numeric PID, the list is traversed to find the matching task_struct. Lines 12 and 13 initialize the loop variables (gdb does not have a for statement in its macro command language), and lines 15 through 17 define the search loop. The find_next_task macro is used to extract the pointer to the next task_struct in the linked list. Finally, if the search fails, a sane return value is set (the address of init_task) so that it can be safely used in other macros.

Building on the find_task macro in Listing 14-11, we can easily create a simple ps command that displays useful information about each process running on the system.

Listing 14-12 defines a gdb macro that displays interesting information from a running process, extracted from the struct task_struct for the given process. It is invoked like any other gdb command, by typing its name followed by any required input parameters. Notice that this user-defined command requires a single argument, either a PID or the address of a task_struct.

Listing 14-12. gdb Macro: Print Process Information

1 define ps

2   # Print column headers

3   task_struct_header

4   set $t=&init_task

5   task_struct_show $t

6   find_next_task $t

7   # Walk the list

8   while &init_task!=$t

9     # Display useful info about each task

10     task_struct_show $t

11     find_next_task $t

12   end

13 end

14

15 document ps

16 Print points of interest for all tasks

17 end

This ps macro is similar to the find_task macro, except that it requires no input arguments and it adds a macro (task_struct_show) to display the useful information from each task_struct. Line 3 prints a banner line with column headings. Lines 4 through 6 set up the loop and display the first task. Lines 8 through 11 loop through each task, calling the task_struct_show macro for each.

Notice also the inclusion of the gdb document command. This allows the gdb user to get help by issuing the help ps command from the gdb command prompt as follows:

(gdb) help ps

 Print points of interest for all tasks

Listing 14-13 displays the output of this macro on a target board running only minimal services.

Listing 14-13. gdb ps Macro Output

(gdb) ps

Address      PID State      User_NIP  Kernel-SP  device comm

0xC01D3750     0 Running              0xC0205E90 (none) swapper

0xC04ACB10     1 Sleeping  0x0FF6E85C 0xC04FFCE0 (none) init

0xC04AC770     2 Sleeping             0xC0501E90 (none) ksoftirqd/0

0xC04AC3D0     3 Sleeping             0xC0531E30 (none) events/0

0xC04AC030     4 Sleeping             0xC0533E30 (none) khelper

0xC04CDB30     5 Sleeping             0xC0535E30 (none) kthread

0xC04CD790    23 Sleeping             0xC06FBE30 (none) kblockd/0

0xC04CD3F0    45 Sleeping             0xC06FDE50 (none) pdflush

0xC04CD050    46 Sleeping             0xC06FFE50 (none) pdflush

0xC054B7B0    48 Sleeping             0xC0703E30 (none) aio/0

0xC054BB50    47 Sleeping             0xC0701E20 (none) kswapd0

0xC054B410   629 Sleeping             0xC0781E60 (none) kseriod

0xC054B070   663 Sleeping             0xCFC59E30 (none) rpciod/0

0xCFFDE0D0   675 Sleeping  0x0FF6E85C 0xCF86DCE0 (none) udevd

0xCF95B110   879 Sleeping  0x0FF0BE58 0xCF517D80 (none) portmap

0xCFC24090   910 Sleeping  0x0FF6E85C 0xCF61BCE0 (none) syslogd

0xCF804490   918 Sleeping  0x0FF66C7C 0xCF65DD70 (none) klogd

0xCFE350B0   948 Sleeping  0x0FF0E85C 0xCF67DCE0 (none) rpc.statd

0xCFFDE810   960 Sleeping  0x0FF6E85C 0xCF5C7CE0 (none) inetd

0xCFC24B70   964 Sleeping  0x0FEEBEAC 0xCF64FD80 (none) mvltd

0xCFE35B90   973 Sleeping  0x0FF66C7C 0xCFEF7CE0 ttyS1  getty

0xCFE357F0   974 Sleeping  0x0FF4B85C 0xCF6EBCE0 (none) in.telnetd

0xCFFDE470   979 Sleeping  0x0FEB6950 0xCF675DB0 ttyp0  bash

0xCFFDEBB0   982<Running   0x0FF6EB6C 0xCF7C3870 ttyp0  sync

(gdb)

The bulk of the work done by this ps macro is performed by the task_struct_show macro. As shown in Listing 14-13, the task_struct_show macro displays the following fields from each task_struct :

• Address Address of the task_struct for the process

• PID Process ID

• State Current state of the process

• User_NIP Userspace Next Instruction Pointer

• Kernel_SP Kernel Stack Pointer

• device Device associated with this process

• comm Name of the process (or command)

It is relatively easy to modify the macro to show the items of interest for your particular kernel debugging task. The only complexity is in the simplicity of the macro language. Because function equivalents such as strlen do not exist in gdb 's user-defined command language, screen formatting must be done by hand.

Listing 14-14 reproduces the task_struct_show macro that produced the previous listing.

Listing 14-14. gdb task_struct_show Macro

 1 define task_struct_show

 2   # task_struct addr and PID

 3   printf '0x%08X %5d', $arg0, $arg0->pid

 4

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату