[New Thread 1062]

[New Thread 1063]

[Switching to Thread 1059]

Breakpoint 1, main (argc=0x1, argv=0xbefffdd4) at tdemo.c:98

98               int c = getchar();

(gdb)

Here we connect to the target (resulting in the ' Remote debugging... ' message in Listing 15-14), set a breakpoint just past the loop where we spawned the new threads, and continue. When the new thread is created, GDB displays a notice along with the thread ID. Thread 1059 is the TDemo application, doing its work directly from the main() function. Threads 1060 through 1063 are the new threads created from the call to pthread_create().

When GDB hits the breakpoint, it displays the message [Switching to Thread 1059], indicating that this was the thread of execution that encountered the breakpoint. It is the active thread for the debugging session, referred to as the current thread in the GDB documentation.

GDB enables us to switch between threads and perform the usual debugging operations such as setting additional breakpoints, examining data, displaying a backtrace, and working with the individual stack frames within the current thread. Listing 15-16 provides examples of these operations, continuing directly with our debugging session started in Listing 15-15.

Listing 15-16. GDB Operations on Threads

...

(gdb) c

Continuing.

                  <<< Ctl-C to interrupt program execution

Program received signal SIGINT, Interrupt.

0x400db9c0 in read () from /opt/mvl/.../lib/tls/libc.so.6

(gdb) i threads

  5 Thread 1063  0x400bc714 in nanosleep ()

   from /opt/mvl/.../lib/tls/libc.so.6

  4 Thread 1062  0x400bc714 in nanosleep ()

   from /opt/mvl/.../lib/tls/libc.so.6

  3 Thread 1061  0x400bc714 in nanosleep ()

   from /opt/mvl/.../lib/tls/libc.so.6

  2 Thread 1060  0x400bc714 in nanosleep ()

   from /opt/mvl/.../lib/tls/libc.so.6

* 1 Thread 1059  0x400db9c0 in read ()

   from /opt/mvl/.../lib/tls/libc.so.6

(gdb) thread 4               <<< Make Thread 4 the current thread

[Switching to thread 4 (Thread 1062)]

#0  0x400bc714 in nanosleep ()

   from /opt/mvl/.../lib/tls/libc.so.6

(gdb) bt

#0  0x400bc714 in nanosleep ()

   from /opt/mvl/.../lib/tls/libc.so.6

#1  0x400bc4a4 in __sleep (seconds=0x0) at sleep.c:137

#2  0x00008678 in go_to_sleep (duration=0x5) at tdemo.c:18

#3  0x00008710 in worker_2_job (random=0x5) at tdemo.c:36

#4  0x00008814 in worker_thread (threadargs=0x2) at tdemo.c:67

#5  0x40025244 in start_thread (arg=0xfffffdfc) at pthread_create.c:261

#6  0x400e8fa0 in clone () at../sysdeps/unix/sysv/linux/arm/clone.S:82

#7  0x400e8fa0 in clone () at../sysdeps/unix/sysv/linux/arm/clone.S:82

(gdb) frame 3

#3  0x00008710 in worker_2_job (random=0x5) at tdemo.c:36

36 go_to_sleep(random);

(gdb) l                    <<< Generate listing of where we are

31      }

32

33      static void worker_2_job(int random)

34      {

35          printf('t2 sleeping for %d ', random);

36          go_to_sleep(random);

37      }

38

39      static void worker_3_job(int random)

40      {

(gdb)

A few points are worth mentioning. GDB assigns its own integer value to each thread and uses these values to reference the individual threads. When a breakpoint is hit in a thread, all threads within the process are halted for examination. GDB marks the current thread with an asterisk (*). You can set unique breakpoints within each threadassuming, of course, that they exist in a unique context. If you set a breakpoint in a common portion of code where all threads execute, the thread that hits the breakpoint first is arbitrary.

The GDB user documentation referenced at the end of this chapter contains more useful information related to debugging in a multithreaded environment.

15.4.3. Debugging Bootloader/Flash Code

Debugging Flash resident code presents its own unique challenges. The most obvious limitation is the way in which GDB and gdbserver cooperate in setting target breakpoints. When we discussed the GDB remote serial protocol in Chapter 14, you learned how breakpoints are inserted into an application.[104] GDB replaces the opcode at the breakpoint location with an architecture-specific opcode that passes control to the debugger. However, in ROM or Flash, GDB cannot overwrite the opcode, so this method of setting breakpoints is useless.

Most modern processors contain some number of debug registers that can be used to get around this limitation. These capabilities must be supported by architecture-and processor-specific hardware probes or stubs. The most common technique for debugging Flash and ROM resident code is to use JTAG hardware probes. These probes support the setting of processor-specific hardware breakpoints. This topic was covered in detail in Chapter 14. Refer back to Section 14.4.2, 'Debugging with a JTAG Probe,' for details.

15.5. Additional Remote Debug Options

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

0

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

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