2010-04-09 22 views
6

Tôi thực sự bối rối bởi điều này!Làm cách nào tôi có thể truy xuất tệp nguồn của một phương thức được biên dịch?

Đối tượng StackFrame (MSDN Link) có phương thức GetFileName trả về đường dẫn gốc của tệp nguồn đã biên dịch phương thức thực thi (các biểu tượng được cung cấp được tạo và bao gồm trong các assembly thực thi). Có vẻ như thông tin này được sử dụng để tạo toàn bộ văn bản ngoại lệ.

Tôi đang cố gắng tìm cách để lấy thông tin này nếu phương pháp hiện không thực thi. Tôi đã poking xung quanh các API phản ánh và đã không nhìn thấy một cách để có được thông tin này. Tôi cho rằng nó phải ở trong đó đâu đó.

Có ai biết phương pháp dựa trên phản chiếu (hoặc thực sự là bất kỳ phương pháp nào khác) có thể lấy cho tôi tên tệp mã không?

Bất kỳ ý tưởng, nhận xét hoặc lạm dụng nào được chấp nhận một cách biết ơn.

Rất cám ơn!

Trả lời

4

Phản ánh chỉ có thể cung cấp thông tin loại từ siêu dữ liệu lắp ráp. Lấy địa chỉ yêu cầu tệp .pdb gỡ lỗi và địa chỉ của hàm trong bộ nhớ, như được biên dịch bởi trình biên dịch JIT. Bạn không thể lấy địa chỉ mà không có phương thức StackFrame.GetNativeOffset() hoặc các giao diện trình gỡ lỗi, giả sử phương thức này thậm chí được biên dịch. Cách tiếp cận thứ hai không thể làm việc trong quá trình, một chương trình không thể gỡ lỗi chính nó.

CLR không gặp bất kỳ sự cố nào vì nó có thể truy xuất địa chỉ phương thức từ khung ngăn xếp khi xử lý ngoại lệ. Đó vẫn là một nghệ thuật không hoàn hảo, nó không thể nhìn thấy địa chỉ của các phương thức được inlined. Có những khung ngăn xếp là bước đầu tiên cần thiết.

+0

Cảm ơn rất nhiều - điều đó có ý nghĩa. Ah well :) –

0

Sử dụng trình biên dịch ngược RedGate Reflector để kiểm tra lắp ráp có chứa lớp.

+0

Cảm ơn bạn đã trả lời. Tôi không biết Reflector có thể làm điều đó - điều đó thật tuyệt vời, nhưng đây là điều tôi muốn có thể làm từ mã vì nó sẽ phù hợp với một hệ thống hiện có. –

1

Bạn có thể đọc thông tin từ tệp .pdb và tự mình đánh giá. Nó chứa tất cả dữ liệu bạn cần. Tôi đã không đọc mã xong nhưng hiểu biết của tôi là thế này:

  • Bạn có mã thông báo siêu dữ liệu từ các phương pháp trong câu hỏi thông qua phản ánh
  • Bạn truy vấn dữ liệu pdb cho rằng dấu hiệu
  • Mục pdb chứa tên tệp và số dòng

Mã thông báo siêu dữ liệu là số 32 bit bao gồm một loại byte và số sê-ri. Mã thông báo đó mô tả mọi thực thể đơn lẻ trong một tệp lắp ráp .NET: loại, nhập tham chiếu, phương thức, trường, v.v. Con số đó đáng giá hơn không gian tên đầy đủ, kiểu, tên phương thức và chữ ký của một phương thức, và nó dễ xử lý hơn. Nhưng lưu ý rằng nó được tạo bởi trình biên dịch và có thể khác nhau trong mọi bản dựng, vì vậy bạn luôn cần tệp .pdb từ cùng một bản dựng.

Tệp pdb chứa các mục nhập về việc IL bù đắp theo phương thức nào đến từ vị trí nguồn nào. Nếu bạn không có StackFrame nhưng chỉ có một phương thức, có thể bạn sẽ tìm thấy nhiều mục nhập về phương pháp để bạn có thể sử dụng một phương thức có độ lệch nhỏ nhất hoặc mô tả toàn bộ phạm vi trong mã nguồn xác định phương thức.

Dưới đây là một số liên kết để đọc thêm, thuật ngữ tìm kiếm là "pdb2xml" mà là một mẫu mã cũ của Microsoft:

Kể từ khi API NET để đọc các tệp .pdb yêu cầu phải có các tệp assembly sẵn có, chuyển đổi này nên được thực hiện trực tiếp sau khi xây dựng để giữ cho tệp XML được tạo ra thực sự di động.

Tôi đang xây dựng phương pháp này trong giải pháp ghi nhật ký .NET của mình, FieldLog, để cho phép phân giải vị trí nguồn từ nhật ký sự cố từ bản phát hành bản phát hành và xóa dấu vết ngăn xếp khỏi các hội đồng bị xáo trộn.

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