2015-04-30 15 views
7

Các Tháo trông giống như:Tại sao tôi không thể tham gia hướng dẫn Cuộc gọi trong khi gỡ lỗi/tháo gỡ?

   methShort(ref x, ref y); 
000007FF00163F67 lea   r8,[rsp+34h] 
000007FF00163F6C lea   rdx,[rsp+30h] 
000007FF00163F71 mov   rcx,qword ptr [rsp+20h] 
000007FF00163F76 mov   rcx,qword ptr [rcx+8] 
000007FF00163F7A mov   rax,qword ptr [rsp+20h] 
000007FF00163F7F call  qword ptr [rax+18h] 

Phương pháp "methShort" là tự động tạo ra trong .NET sử dụng Reflection.Emit. Phải mất hai tham số Int32 là giá trị "byRef". Điều này đang được gỡ lỗi dưới dạng bản dựng "chế độ phát hành".

Tôi có thể thực hiện từng bước trong quá trình lắp ráp theo hướng dẫn "gọi". Nội dung của bộ nhớ được chỉ ra bởi R8 và RDX (các tham số) trông ổn. Tôi không biết loại phép thuật nào cho phép JIT sử dụng thanh ghi cho cuộc gọi thay vì ngăn xếp, nhưng đó là bên cạnh điểm.

Khi tôi cố gắng "Bước vào" lệnh gọi, trình gỡ lỗi "bước qua" thay vào đó. Các thói quen thực sự được gọi là - phương pháp thực hiện chức năng của nó một cách chính xác. Nhưng tôi dường như không thể tháo rời hay bước vào phương pháp.

Tại thời điểm ngay trước cuộc gọi, RAX chứa giá trị 00000000025C67A8h. Khi 18h được thêm vào đó, địa chỉ cho indirection trở thành 00000000025C67C0h. QWORD tại địa chỉ này là 000000001b64dc48h.

Nếu tôi cố gắng tháo rời địa chỉ này (000000001b64dc48h), trình gỡ rối quay trở lại với "Địa chỉ được chỉ định không thể hiển thị. Không có mã tại vị trí được cung cấp".

Như một nỗ lực Hail Mary, tôi đã cố gắng tháo mã tại RAX mà không có sự gián đoạn, nhưng như tôi mong đợi điều này cũng không thành công.

Bất cứ ai có thể cho tôi biết cách truy cập vào bất kỳ mã nào tại địa chỉ hoặc nếu có điều gì đó giống với LEA cần được thực hiện trên địa chỉ (RAX + 18h) trước khi tháo mã đó?

+3

https://msdn.microsoft.com/en-us/library/ms235286.aspx trên x64 hai thông số đầu tiên của cuộc gọi phương thức có trong RCX và RDX. – xanatos

+1

VS từ chối cho bạn thấy một số phần của thời gian chạy. Đây phải là cuộc gọi trợ giúp thời gian chạy. Tôi không bao giờ hiểu tại sao họ hoàn toàn chắc chắn rằng trình gỡ lỗi thậm chí không thể tháo rời thời gian chạy. – usr

Trả lời

6

Bạn cần lưu ý rằng trình gỡ lỗi đang cố gắng cứu bạn khỏi lãng phí vài giờ trong cuộc sống của bạn. methShort() là cuộc gọi đại biểu, vẫn cần phải hoàn thành công việc trước khi cuộc gọi đó hoàn tất. Bạn sẽ không thưởng thức một bước thông qua jitter biên dịch phương pháp năng động của bạn để mã máy, CAS kiểm tra nhu cầu liên kết, CLR tạo ra các sơ khai đại biểu và ràng buộc nó vào trang web cuộc gọi.

Tôi sẽ trả lời câu hỏi như được đăng, trình gỡ lỗi sẽ không hiển thị cho bạn mã đích của cuộc gọi vì đó là mã không được quản lý. Bạn có thể nói từ địa chỉ, cách xa khỏi vị trí của mã jitted của bạn. Thuyết phục nó rằng bạn muốn nhìn thấy nó đòi hỏi nhiều thủ đoạn:

  • Project + Thuộc tính, Debug tab, đánh dấu vào ô "Enable mã gỡ lỗi mẹ đẻ" tùy chọn
  • Bạn cần phải chuyển đổi các chương trình gỡ rối từ quản lý sang chế độ không được quản lý. Không có lệnh rõ ràng cho rằng, cách đơn giản nhất tôi biết làm thế nào để làm điều đó là sử dụng cửa sổ Call Stack. Bấm đúp vào khung dưới cùng (__RtlUserThreadStart @ 8).
  • Nhấp vào liên kết "xem tháo gỡ" trong cửa sổ bật lên Không có nguồn để bạn quay lại cửa sổ Tháo gỡ. Trình gỡ lỗi hiện ở chế độ không được quản lý. Cẩn thận rằng bạn không thể dễ dàng biết được nữa với công cụ gỡ lỗi mới vì nó hiện hiển thị các địa chỉ mã thích hợp.
  • Bây giờ bạn có thể nhập địa chỉ bạn đã phát hiện trong hộp Địa chỉ. Hãy chắc chắn để đặt "0x" ở phía trước của nó.

Không có khả năng hữu ích để gỡ lỗi phương pháp động, mặc dù tôi đã nhanh chóng ném khăn khi tôi thử.Có thể bạn đang ở phía trước bằng cách gọi phương thức hai lần để bạn có thể bỏ qua tất cả phí trên cuộc gọi thứ hai. Xem xét việc đặt một cuộc gọi đến Debugger.Break() trong phương thức của bạn.

Các vấn đề liên quan