2012-02-29 30 views
6

Tôi đang phát triển một ứng dụng iOS gần đây đã phát triển một cơ sở C++ lớn. C++ không phải là sở trường của tôi, và tôi nhận được thất vọng bởi các ngoại lệ. Những gì tôi đang tìm kiếm là một cách để có được một theo dõi ngăn xếp đến trang web của một ném ngoại lệ (un-xử lý). Tôi sẽ nói rằng vòng loại "không xử lý" là tùy chọn; Tôi sẽ giải quyết để phá vỡ bất kỳ bất kỳ trường hợp ngoại lệ ném như là một phương sách cuối cùng, mặc dù ngoại lệ chưa xử lý là lý tưởng.Tôi có thể lấy dấu vết ngăn xếp cho các ngoại lệ C++ không được xử lý (Mục tiêu) không?

Điều tôi hiện đang nhận được là vô ích. Giả sử tôi không có bất kỳ xử lý ngoại lệ thích hợp cao hơn lên callstack, và tôi làm điều gì đó như

std::vector<int> my_vector; 
my_vector.at(40) = 2; // Throws std::out_of_range 

Ứng dụng sẽ phá vỡ trong main() và tôi sẽ nhận được một thông điệp log nói "chấm dứt gọi là ném một ngoại lệ." Không hữu dụng.

Việc đặt các khối try/catch chung lên cao hơn cũng không giúp ích gì, bởi vì callstack bị bỏ trong quá trình xử lý ngoại lệ đến điểm của khối catch, khiến tôi không biết đến nguồn gốc thực sự của ngoại lệ. Điều này cũng áp dụng cho việc cung cấp terminate_handler của riêng tôi. Các xác nhận hữu ích hơn, nhưng chúng yêu cầu tôi dự đoán các điều kiện lỗi ở một mức độ nào đó, điều mà tôi không thể luôn làm. Tôi vẫn muốn trình gỡ rối có thể bước vào ngay cả khi một ngoại lệ không mong muốn làm cho nó vượt qua các số assert() trước tiên của tôi.

Điều tôi muốn tránh là phải bao bọc mọi cuộc gọi có thể có thể ném một ngoại lệ trong khối try/catch chỉ để có được dấu vết ngăn xếp đến lỗi. Khi chạy, tôi thực sự không quan tâm đến việc bắt những ngoại lệ này. Khi chúng xảy ra, nó có nghĩa là có một lỗ hổng nghiêm trọng trong việc thực hiện chương trình, và không có cách nào nó có thể tiếp tục bình thường. Tôi chỉ muốn được thông báo để tôi có thể xác định nguyên nhân và sửa đổi vấn đề để nó không xảy ra lần nữa.


Trong Objective C, tôi có thể đặt một breakpoint biểu tượng trên objc_exception_throw, và bất cứ lúc nào tôi vít cái gì đó lên tôi ngay lập tức sẽ phá vỡ thực hiện và được trình bày với một vết đống đẹp vì vậy tôi biết nơi vấn đề là . Rất hữu ích.

Tôi nhận thấy hành vi này thực sự chỉ hữu ích vì sự khác biệt triết học trong xử lý ngoại lệ giữa hai ngôn ngữ. Các ngoại lệ C mục tiêu chỉ nhằm mục đích biểu thị các lỗi không thể khôi phục. Nhiệm vụ xử lý lỗi thông thường được thực hiện thông qua các mã trả về lỗi. Điều này có nghĩa là bất kỳ ngoại lệ C mục tiêu nào là ứng cử viên tuyệt vời cho điểm dừng cho nhà phát triển.

C++ dường như có cách sử dụng khác cho Ngoại lệ. Chúng được sử dụng để xử lý cả hai lỗi nghiêm trọng lỗi thường gặp (ít nhất là trong libs của bên thứ ba mà tôi đang sử dụng). Điều này có nghĩa là tôi có thể không thực sự muốn phá vỡ mọi ngoại lệ được ném vào C++, nhưng tôi vẫn sẽ thấy khả năng hữu ích nếu tôi không thể chỉ phá vỡ các ngoại lệ chưa được xử lý.

+0

C++ ngoại lệ không thực sự dành cho các lỗi _routine_, nhưng đôi khi chúng bị lạm dụng. Đúng là chúng không chỉ dành cho các lỗi không thể khôi phục. – bames53

Trả lời

5

Bạn có thể nhanh chóng thiết lập một đột phá trên tất cả các C++ ném điều kiện trong Xcode:

  • cmd+6
  • nút "+" -> Add Exception Breakpoint
    • C++ ->std::out_of_range
    • On Ném

Cập nhật

Nếu bạn có rất nhiều trong số họ tho lọc ra, bạn có thể thích:

  • Tạo Symbolic Breakpoint
  • Symbol = __cxa_throw (có thể thay đổi theo thư viện std)
  • Action> Debugger command = bt
  • Tự động tiếp tục sau khi eval = On

Các bt bản ghi lệnh các vết lùi. Cấu hình theo cách này, nó sẽ tự động tiếp tục.

Vì vậy, điều này sẽ chỉ cần đăng nhập các vết lùi của mỗi ngoại lệ ném - khi chương trình của bạn chấm dứt do một ngoại lệ unhandled, các manh mối sẽ là một trong những vết lùi Logged thức (thường là cuối cùng, trừ trường hợp rethrows thư viện).

+2

Ah, ngay trong giao diện người dùng. Hoàn hảo. –

+0

Và tôi vẫn đấu tranh. Có vẻ như bạn sẽ có thể chỉ định một số ngoại lệ nhất định để phá vỡ. Tôi đang sử dụng ZXing, mà ném ngoại lệ hoàn toàn ở khắp mọi nơi (Một số mỗi khung hình, trong hoạt động bình thường). Tôi cần phải bỏ qua những điều này. Tuy nhiên, khi tôi thiết lập một điểm dừng trên một cái gì đó hoàn toàn không liên quan như 'std :: out_of_range', điểm ngắt vẫn được kích hoạt trên tất cả các lớp con ngoại lệ của ZXing ::. Điều này có bình thường không? –

+0

@MattWilding ok. cập nhật với một góc khác cho trường hợp này. – justin

1

Trong ứng dụng tôi nhận được để gỡ lỗi với nhiều ngoại lệ c + +, tôi để lại "Catch C++ ngoại lệ về Throw" cho đến khi tôi nhận được điểm trong ứng dụng, nơi nó sẽ ném ngoại lệ, sau đó tôi bật tùy chọn đó và thường là ngoại lệ tiếp theo được ném là những gì tôi đang tìm kiếm. Điều này sẽ phá vỡ một vài cấp độ sâu hơn nơi lỗi, nhưng ngăn xếp là nguyên vẹn, do đó bạn có thể tìm ra những gì đang xảy ra.

0

Kiểm tra PLCrashReporter. Chúng tôi sử dụng nó với ứng dụng của chúng tôi (dựa chủ yếu vào C++) và nó tạo ra các dấu vết ngăn xếp ngay cả đối với mã C++.

Vấn đề duy nhất bạn có thể có là khi sử dụng thói quen lắp ráp mà không được viết nguyên bản dành cho iOS (trình biên dịch của Apple đang sử dụng R7 để giữ stack frame để truy tìm lại những biểu tượng mà không theo ARM chính thức EBI)

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