2012-03-23 43 views
20

Tôi đang gỡ lỗi phần mềm này cho một hệ thống nhúng STM32. Trong một trong những chức năng chương trình của tôi tiếp tục đánh một số loại breakpoint:SIGTRAP mặc dù không có điểm ngắt được đặt; điểm ngắt phần cứng ẩn?

SIGTRAP, Trace/bẫy breakpoint

Tuy nhiên, trong GDB, khi tôi làm info breakpoints tôi nhận được No breakpoints or watchpoints. Điểm ngắt thực sự tương ứng với điểm ngắt mà tôi đã đặt khá lâu trước đây, trong một phiên bản khác của tệp thực thi. Khi tôi đặt điểm ngắt đó, GDB đã nói với tôi automatically using a hardware breakpoint on read-only memory (hoặc một thông báo tương tự).

Tôi nghĩ điểm ngắt phần cứng vẫn còn trên chip của tôi, mặc dù đã tải phiên bản phần mềm mới. Nếu có thực sự là một điểm ngắt giả mạo, làm thế nào tôi có thể xác định vị trí và loại bỏ nó?

+0

Đặt lại CPU. :) (hw điểm ngắt có thể được cài đặt lại, nếu gdb chết hoặc nếu nó không xóa tất cả các điểm ngắt hiện có trên lối ra/kết nối lại). – dbrank0

+0

Lưu ý rằng đăng ký gỡ lỗi có thể tồn tại trên một số loại đặt lại. Một thiết lập lại nguồn đầy đủ chắc chắn sẽ xóa nó. – TJD

+1

Bạn có ý nghĩa gì với "thiết lập lại nguồn đầy đủ"? Tôi đã thử rút/replugging, nhưng breakpoint vẫn tồn tại. – Randomblue

Trả lời

18

Ok. Câu trả lời dài: Điểm ngắt phần cứng thường được thiết lập bằng cách ghi vào một số thanh ghi CPU đặc biệt. Điều này được thực hiện bởi gdb. Nếu gdb chết, nó có thể để lại những cài đặt trong CPU. Tôi đoán việc triển khai của bạn (của gdb) không rõ ràng hoặc kiểm tra chúng, khi nó kết nối với mục tiêu của bạn. Để định vị chúng, bạn cần liệt kê các nội dung của thanh ghi phần cứng breakpoints trên CPU của bạn (không biết cách thực hiện điều này trên STM32). Workaround sẽ được (thông báo đoán) được điều này: thiết lập vài điểm ngắt HW (thường chỉ có một vài, ít khi hơn 8) bằng cách sử dụng gdb, sau đó loại bỏ tất cả chúng. Điều này sẽ ghi đè lên và sau đó làm sạch các thanh ghi hw đó. Khi bạn đã thiết lập các điểm ngắt đó (trước khi loại bỏ chúng), hãy "tiếp tục" (chỉ trong trường hợp, vì gdb đặt các điểm ngắt tại thời điểm đó).

+1

Cảm ơn ý tưởng thiết lập nhiều điểm ngắt, và sau đó loại bỏ chúng. Điều đó sẽ giải quyết vấn đề. Một chút khó chịu rằng gdb không xóa những điểm ngắt khi nó kết nối với mục tiêu của tôi. – Randomblue

1

Mã bạn đang chạy có thể chứa

int $0x03 ; talking about x86, don't know STM32 mnemo 

mà gọi một SIGTRAP.

2

SIGTRAP phải là lệnh breakpoint đang được chạy.

Gỡ lỗi này bằng cách kiểm tra con trỏ chỉ dẫn của bạn, rất có thể là chỉ vào một địa chỉ chứa lệnh BKPT (bạn sẽ phải tra cứu mã thực tế là gì).

Từ đó bạn sẽ phải làm việc ngược dựa trên ngăn xếp và con trỏ chỉ dẫn và xem bạn có đang ở nơi bạn mong muốn không. Có thể có một số điều gây ra điều này, từ GDB chèn một lệnh breakpoint mà nó không thể xóa, để tham nhũng bộ nhớ.

2

Sau đây giúp tôi:

# Ones I hit the SIGTRAP: 
(gdb) f 0 # Show the current stack frame of the current thread. 
#0 0x4003ed70 in [email protected]@GLIBC_2.4() from /opt/CodeSourcery/arm-2011.09/arm-none-linux-gnueabi/libc/lib/libpthread.so.0 

# The fragment of interest is the current address: 0x4003ed70. 
# Set the hardware assisted breakpoint at the current address: 
(gdb) hbreak *0x4003ed70 

# Continue execution (without hitting SIGTRAP): 
(gdb) c 
# Continuing. 
+1

Đây là ý tưởng giống như câu trả lời được chấp nhận, nhưng bạn nên lưu ý rằng lệnh hbreak là chìa khóa. Lệnh break thông thường sẽ thiết lập các điểm ngắt phần mềm thay vì ghi đè các điểm ngắt trước đó –

0

Nếu thêm và loại bỏ breakpoint phần cứng không giúp đỡ, kiểm tra các vector ngắt.

Trên bộ vi điều khiển Cortex-M, tất cả các mục bộ xử lý phải có địa chỉ lẻ (ARM Cortex-M FAQ). Nếu không, thì một UsageFault loại INVSTATE được kích hoạt và MCU bị tạm dừng. GDB diễn giải điều này như là một SIGABRT.

Nếu một trong những mục có địa chỉ chẵn, sau đó kiểm tra xem chức năng xử lý có .thumb_func.type chỉ thị (NXP Avoid hardfault, HardFault and .thumb_func).

Ví dụ cho một HardFault_Handler:

.thumb_func 
.type HardFault_Handler, %function 
HardFault_Handler: 
    TST LR, #4 
    ITE EQ 
    MRSEQ R0, MSP 
    MRSNE R0, PSP 
    B hard_fault_handler_c 
Các vấn đề liên quan