2014-07-15 14 views
5

Dòng tiêu đề cơ bản nói lên tất cả.Trong GDB có thể đưa ra một địa chỉ tương đối (trong dòng) từ khi bắt đầu một hàm không?

Nếu tôi cung cấp vị trí dựa trên tệp và số dòng, giá trị đó có thể thay đổi nếu tôi chỉnh sửa tệp. Trong thực tế, nó có xu hướng thay đổi khá thường xuyên và một cách bất tiện nếu tôi chỉnh sửa nhiều hơn một hàm duy nhất trong quá trình tái cấu trúc. Tuy nhiên, nó ít có khả năng thay đổi nếu nó (line-) liên quan đến đầu của một hàm.

Trong trường hợp không thể cung cấp cho dòng bù đắp từ đầu của một hàm, thì có lẽ có thể sử dụng các biến tiện lợi để mô phỏng nó không? I E. nếu tôi sẽ khai báo các biến tiện lợi mà ánh xạ tới sự bắt đầu của một hàm cụ thể (một danh sách mà tôi sẽ tiếp tục cập nhật)?

Theo help break dường như không có sẵn, nhưng tôi nghĩ tôi nên hỏi chắc chắn hơn.


(gdb) help break 
Set breakpoint at specified line or function. 
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION] 
PROBE_MODIFIER shall be present if the command is to be placed in a 
probe point. Accepted values are `-probe' (for a generic, automatically 
guessed probe type) or `-probe-stap' (for a SystemTap probe). 
LOCATION may be a line number, function name, or "*" and an address. 
If a line number is specified, break at start of code for that line. 
If a function is specified, break at start of code for that function. 
If an address is specified, break at that exact address. 
With no LOCATION, uses current execution address of the selected 
stack frame. This is useful for breaking on return to a stack frame. 

THREADNUM is the number from "info threads". 
CONDITION is a boolean expression. 

Multiple breakpoints at one place are permitted, and useful if their 
conditions are different. 

Do "help breakpoints" for info on other commands dealing with breakpoints. 

Trả lời

5

Đó là một yêu cầu lâu dài để thêm video này vào gdb. Tuy nhiên, nó không tồn tại ngay bây giờ. Nó có thể là loại có thể với Python, nhưng có lẽ không hoàn toàn, vì Python hiện không có quyền truy cập vào tất cả các sự kiện thiết lập lại điểm ngắt (do đó điểm ngắt có thể hoạt động một lần nhưng không chạy lại hoặc tải thư viện hoặc một số thay đổi kém khác).

Tuy nhiên, văn bản được trích dẫn hiển thị một cách đẹp hơn - sử dụng điểm thăm dò. Đây được gọi là "điểm thăm dò của SystemTap", nhưng trên thực tế chúng giống với tính năng ELF + GCC chung hơn - chúng có nguồn gốc từ dự án SystemTap nhưng không phụ thuộc vào nó. Điều này cho phép bạn đánh dấu một điểm trong nguồn và dễ dàng đặt điểm ngắt trên đó, bất kể các chỉnh sửa khác đối với nguồn. Chúng đã được sử dụng trên các bản phân phối Linux để đánh dấu các vị trí đặc biệt trong các trình tự thời gian chạy không cần thiết và lâu dài để thực hiện công việc gỡ lỗi độc đáo trong sự hiện diện của chúng.

+0

Ngoài điểm thăm dò, tôi cũng đã sử dụng cú pháp 'phá vỡ hàm: nhãn' cho nhiều tác dụng tương tự trong quá khứ. đó cũng có thể là một lựa chọn. – matt

+0

@TomTromey: SystemTap cũng là một Linux cụ thể, phải không? Trong khi đó ELF, GCC và GDB thì không. – 0xC0000022L

+0

Vâng, SystemTap là đặc trưng cho Linux. Tuy nhiên, có thể sử dụng đầu dò sdt.h trên các hệ thống khác. Tôi đã không cố gắng nhưng tôi không thấy tại sao không. Toàn bộ mặt devel của đầu dò chỉ là một tập tin tiêu đề duy nhất ... –

0

Tôi hiểu rằng đây là một câu hỏi cũ, nhưng tôi vẫn không thể tìm ra giải pháp tốt hơn ngay cả bây giờ trong năm 2017. Đây là giải pháp Python.Có lẽ nó không phải là mạnh mẽ nhất/sạch một, nhưng nó hoạt động rất tốt trong nhiều tình huống thực tế:

class RelativeFunctionBreakpoint (gdb.Breakpoint): 
    def __init__(self, functionName, lineOffset): 
     super().__init__(RelativeFunctionBreakpoint.calculate(functionName, lineOffset)) 

    def calculate(functionName, lineOffset): 
     """ 
     Calculates an absolute breakpoint location (file:linenumber) 
     based on functionName and lineOffset 
     """ 
     # get info about the file and line number where the function is defined 
     info = gdb.execute("info line "+functionName, to_string=True) 
     # extract file name and line number 
     m = re.match(r'Line[^\d]+(\d+)[^"]+"([^"]+)', info) 
     if not m: 
      raise Exception('Failed to find function %s.' % functionName) 
     line = int(m.group(1))+lineOffset #add the lineOffset 
     fileName = m.group(2) 
     return "%s:%d" % (fileName, line) 

SỬ DỤNG:

cơ bản:

RelativeFunctionBreakpoint("yourFunctionName", lineOffset=5) 

tùy chỉnh breakpoint:

class YourCustomBreakpoint (RelativeFunctionBreakpoint): 
    def __init__(self, funcName, lineOffset, customData): 
     super().__init__(funcName, lineOffset) 
     self.customData = customData 
    def stop(self): 
     # do something 
     # here you can access self.customData 
     return False #or True if you want the execution to stop 

Ưu điểm của giải pháp

  • tương đối nhanh, vì breakpoint được thiết lập một lần duy nhất, trước khi thực hiện bắt đầu
  • mạnh mẽ với những thay đổi trong tập tin nguồn nếu họ không ảnh hưởng đến chức năng

Disadvatages

  • Tất nhiên, nó không mạnh mẽ đối với các chỉnh sửa trong chính chức năng
  • Không mạnh mẽ với những thay đổi trong cú pháp đầu ra của lệnh dòng thông tin funcName gdb (có thể có cách tốt hơn để trích xuất tên tệp và số dòng)
  • khác? bạn chỉ ra
Các vấn đề liên quan