Tôi cần in dấu vết ngăn xếp từ trình xử lý tín hiệu của ứng dụng C++ mutli-luồng C++ chạy trên Linux. Mặc dù tôi đã tìm thấy một số ví dụ mã, nhưng không có mã nào trong số đó biên dịch được. Điểm chặn của tôi là nhận được địa chỉ của người gọi (điểm mà tín hiệu được tạo ra) từ cấu trúc ucontext_t. Tất cả thông tin tôi có thể tìm thấy, trỏ tới thanh ghi EIP dưới dạng ucontext.gregs [REG_EIP] hoặc ucontext.eip. Có vẻ như cả hai đều là x86. Tôi cần mã tuân thủ 64 bit cho cả CPU Intel và AMD. Ai có thể giúp được không?In dấu vết ngăn xếp từ trình xử lý tín hiệu
Trả lời
Cách thông thường nhận được một vết đống là để lấy địa chỉ của một biến địa phương, sau đó thêm một số con số kỳ diệu với nó, tùy thuộc vào cách trình biên dịch tạo ra mã (có thể phụ thuộc vào các tùy chọn tối ưu hóa sử dụng để biên dịch mã) và làm việc trở lại từ đó. Tất cả các hệ thống rất phụ thuộc, nhưng có thể làm được nếu bạn biết những gì bạn đang làm.
Việc này có hoạt động trong trình xử lý tín hiệu hay không là một câu hỏi khác. Tôi không biết về nền tảng mà bạn mô tả, nhưng rất nhiều hệ thống cài đặt ngăn xếp riêng biệt cho bộ xử lý tín hiệu , không có liên kết quay lại ngăn xếp bị gián đoạn trong bộ nhớ người dùng có thể truy cập.
Bạn có nghĩa là không có liên kết quay lại ngăn xếp bị gián đoạn không? –
@wood_brian Không có trong bộ nhớ có thể truy cập của người dùng. (Hệ điều hành rõ ràng giữ thông tin theo một cách nào đó.) –
Bạn đã viết bị gián đoạn tĩnh. Tôi nghĩ bạn có nghĩa là ngăn xếp bị gián đoạn. –
có chức năng glibc backtrace. Trang người dùng liệt kê ví dụ về cuộc gọi:
#define SIZE 100
void myfunc3(void) {
int j, nptrs;
void *buffer[100];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
would produce similar output to the following: */
strings = backtrace_symbols(buffer, nptrs);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
for (j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings);
}
Xem trang hướng dẫn để biết thêm ngữ cảnh.
thật khó để biết liệu điều này có thực sự được đảm bảo để hoạt động từ trình xử lý tín hiệu hay không, vì posix chỉ liệt kê một vài hàm reentrant được đảm bảo hoạt động. Hãy nhớ rằng: một trình xử lý tín hiệu có thể được gọi trong khi phần còn lại của tiến trình của bạn nằm ngay giữa cuộc gọi malloc.
My đoán là, điều này thường hoạt động, nhưng đôi khi có thể không thành công. Để gỡ lỗi này có thể là đủ tốt.
- 1. Trang Lỗi - cách in dấu vết ngăn xếp trong JSP
- 2. Cách in dấu vết ngăn xếp của StackOverflowException
- 3. In dấu vết ngăn xếp trong C++ (MSVC)?
- 4. Ngăn xếp tín hiệu
- 5. Làm thế nào để buộc máy ảo của python in dấu vết ngăn xếp?
- 6. Lấy dấu vết ngăn xếp từ SBT với Scala
- 7. Tín hiệu Xử lý bằng Python Chủ đề
- 8. Dấu vết ngăn xếp ngoại lệ Javascript
- 9. Cách tìm dấu vết ngăn xếp này?
- 10. SIGKILL tín hiệu xử lý
- 11. Bắt dấu vết ngăn xếp trong Perl?
- 12. Làm cách nào để in dấu vết ngăn xếp thời gian chạy của quá trình Ruby 1.9?
- 13. Cách in dấu vết ngăn xếp từ bố cục tùy chỉnh logback?
- 14. Tìm dấu vết ngăn xếp thực tế Java từ theo dõi ngăn xếp JavaScript
- 15. Tín hiệu nhận được chương trình SIGTRAP, Dấu vết/dấu ngắt điểm
- 16. Gói Python để xử lý tín hiệu
- 17. Cách lấy dấu vết ngăn xếp của một chủ đề
- 18. Xử lý tín hiệu trong C
- 19. Vấn đề với xử lý tín hiệu, xử lý ngắt
- 20. __forwarding__ trong dấu vết ngăn xếp nghĩa là gì?
- 21. Xử lý tín hiệu trong chương trình song song OpenMP
- 22. Dấu vết ngăn xếp C++ di động khi ngoại lệ
- 23. Điểm hủy trong trình xử lý tín hiệu?
- 24. nhận dấu vết ngăn xếp trên lỗi tryCatch'ed trong R
- 25. Xử lý tín hiệu Erlang Linux
- 26. XOPEN_SOURCE và xử lý tín hiệu
- 27. Lập trình 'Nghe' với Âm thanh (Xử lý Tín hiệu?)
- 28. Tắt dấu vết ngăn xếp HTML bằng Xdebug
- 29. Wheres dấu vết ngăn xếp của tôi đã biến mất?
- 30. tín hiệu xử lý trong C++
Nó sẽ không làm tôi ngạc nhiên nếu nó không thể làm được. Bạn đã thử làm nó trên 32bit chưa? Ngoài ra, mà distro? –
Trong 64 bit, thanh ghi là RIP. Khá chắc chắn nó sẽ ở trong một nơi nào đó. –
Đó là Red Hat 4.1.2-50. Không thể là ứng dụng 32 bit khi chúng tôi làm việc với các vùng bộ nhớ lớn lên đến 60+ GB – GMichael