2013-01-24 18 views
7

Tôi có một ứng dụng C++ có rất nhiều chủ đề và hầu hết trong số đó là với kích thước ngăn xếp 32k. Vấn đề là đôi khi tôi nhận được một stackoverflow và tôi muốn phát hiện mà thread đã gây ra stackoverflow và ghi nó vào tập tin đăng nhập, vấn đề là tôi không thể bẫy nó.Làm thế nào để bẫy tràn ngăn xếp với pthread?

Tôi đọc về số SIGSEGV và tôi chỉ có thể bẫy tín hiệu này mà không có chủ đề. Tôi cũng đã thử sử dụng pthread_sigmask() và sử dụng libsigsegv nhưng tôi cũng không thành công.

Có ai có thể cho tôi xem một ví dụ nhỏ về việc bẫy SIGSEGV khi xảy ra tràn ngăn xếp trong chuỗi không?

Trả lời

8

Lỗi ngăn xếp ngăn xếp cho một ứng dụng đa luồng, phần lớn, không khác gì so với làm như vậy cho một ứng dụng đơn luồng. Cách chính nó có thể khác nhau là nếu bạn bị tràn bởi một lề lớn; cho chủ đề chính; điều này sẽ vẫn để lại cho bạn một con trỏ ngăn xếp không hợp lệ và SIGSEGV trong hầu hết các trường hợp, nhưng với ngăn xếp nhỏ, tràn có thể đặt con trỏ ngăn xếp của bạn ở giữa ngăn xếp của một chuỗi khác, trong trường hợp đó những điều rất xấu sẽ xảy ra và không có hy vọng tiến bộ về phía trước. Một vấn đề khác bạn nên kiểm tra, nếu bạn đang sử dụng ngăn xếp nhỏ, là bạn không vô hiệu hóa các trang bảo vệ. Sử dụng pthread_attr_setstack (chức năng này không còn được dùng nữa) sẽ không cung cấp cho bạn các trang bảo vệ trừ khi bạn đã tự thiết lập chúng. Sử dụng pthread_attr_setstacksize (giao diện hiện đại thích hợp) không được can thiệp vào việc phân bổ trang bảo vệ, nhưng bạn có thể muốn tăng kích thước bảo vệ (với pthread_attr_setguardsize) nếu bạn cho rằng luồng của mình bị chênh lệch lớn.

Với điều đó đã nói, quy trình chung để xử lý tràn ngăn xếp là thiết lập trình xử lý cho SIGSEGV và đặt thành chạy trên ngăn xếp thay thế. Điểm cuối cùng này rất quan trọng! Khi con trỏ ngăn xếp không hợp lệ tại thời điểm tín hiệu được tạo ra, cần phải có một ngăn xếp thay thế để bộ xử lý tín hiệu tự chạy. Trong khi cờ cho dù một tín hiệu đã cho được xử lý trên ngăn xếp thay thế có phải là thuộc tính cho mỗi tín hiệu (được đặt bởi sigaction), thì ngăn thay thế thực tế là một thuộc tính cho mỗi luồng. Mỗi luồng phải đặt ngăn xếp thay thế riêng của mình sử dụng sigaltstack. Không gian cho ngăn xếp thay thế có thể được phân bổ thông qua malloc hoặc mmap, nhưng cách dễ nhất để thực hiện là chỉ tạo một mảng tự động char có kích thước khoảng 2-4k trong chức năng bắt đầu chuỗi và sử dụng cho ngăn xếp thay thế. Về cơ bản, những gì số tiền này để làm là đặt một phạm vi nhỏ tại dưới cùng của của ngăn xếp của chủ đề được sử dụng như không gian ngăn xếp khẩn cấp cho bộ xử lý tín hiệu sau khi đầu tràn ngăn xếp.