2015-02-17 15 views
7

Người Java ở đây bị kẹt làm một số C++. Tôi đang bắt một ngoại lệ và cố gắng để chẩn đoán nơi nó đến từ (đáng tiếc là ngoại lệ không được ném khi chạy qua gdb). Tuy nhiên, khi tôi in ra những gì() của trường hợp ngoại lệ, tôi chỉ nhận được chuỗi "std :: exception". Điều này có cụ thể đối với bất kỳ điều gì trong thư viện chuẩn hoặc thực hiện rất nhiều ngoại lệ tiêu chuẩn trả về điều này không? Dưới đây là những gì tôi đang làm để in:std :: exception's what() trả về "std :: exception"

} catch (const std::exception & ex) { 
     std::cout << ex.what() << std::endl; 
    } 

Kết quả chỉ là:

std::exception 

Ngoài ra, tôi đang làm việc trong một mã-base khá lớn, có thể là này là đến từ một số ngoại lệ về phía chúng tôi nhưng tôi vẫn chưa tìm thấy nó thông qua các kỹ thuật tìm kiếm thông thường vì vậy tôi hiện đang hướng tới điều này đến từ các thư viện chuẩn.

Tôi đang sử dụng g ++ 4.8 nếu có liên quan.

+0

Bạn có nhận được kết xuất cốt lõi mà bạn có thể tải lên trong gdb và thực hiện backtrace không? –

+0

Trường hợp ngoại lệ được ném ở đâu? Nó bị ném như thế nào? Ngoại lệ gì được ném? Vui lòng tạo [Ví dụ tối thiểu, hoàn chỉnh và có thể xác minh] (http://stackoverflow.com/help/mcve) và hiển thị cho chúng tôi. –

+0

Điều đó có vẻ bất thường đối với một ngoại lệ thư viện GCC - tôi mong đợi một lớp dẫn xuất cụ thể hơn như 'std :: runtime_error',' std :: length_error', vv (một trong những [this] (http: //en.cppreference. com/w/cpp/error/exception)) với '.what()' giao tiếp điều đó. Tôi nghĩ rằng điều này có lẽ là từ bên trong cơ sở mã của riêng bạn. Có thể không giúp đỡ, nhưng nếu tôi muốn bạn thử một grep đệ quy cho ''throw \ s + std :: exception'' trong mã của riêng bạn, và nếu điều đó không bật lên bất cứ điều gì bạn có thể thử GCC tiêu đề. –

Trả lời

3

Ngoại lệ C++ hoàn toàn khác với ngoại lệ Java.

C++ tiêu chuẩn xác định rằng chuỗi trả về bởi những gì() là hoàn toàn tùy ý, và thực hiện xác định:

virtual const char* what() const noexcept; 

Returns: An implementation-defined ntbs. 
Remarks: The message may be a null-terminated multibyte string 
(17.5.2.1.4.2), suitable for conversion 
and display as a wstring (21.3, 22.4.1.4). The return value remains 
valid until the exception object 
from which it is obtained is destroyed or a non-const member 
function of the exception object is called. 

Giá trị trả lại bạn đang nhận được, "std :: ngoại lệ" là hoàn toàn phù hợp với tiêu chuẩn C++.

Không dựa vào ngoại lệ C++ để cho bạn biết chính xác nơi chúng được đưa ra sau khi bạn bắt chúng, như Java. Điều này nằm ngoài phạm vi của tiêu chuẩn C++. Trong C++, một ngoại lệ thực sự không có gì hơn là một cơ chế để truyền luồng điều khiển thực thi. Đã nói rằng: nhiều triển khai C++ sẽ cung cấp cho bạn một số cơ chế thực hiện cụ thể để bán phá giá backtrace stack hiện tại, với khả năng tốt nhất của thư viện thời gian chạy. Kiểm tra tài liệu của trình biên dịch C++ để biết thêm thông tin. Ví dụ:

gcc, cung cấp backtrace(), cùng với một số chức năng nội bộ gcc để chuyển đổi địa chỉ thô được trả về bằng dấu phẩy() thành biểu tượng và các chức năng khác. Sử dụng nó, một sự tương tự thô với xử lý ngoại lệ của Java có thể được pha trộn; mặc dù việc thực thi gcc không hoàn hảo, và có một số lỗ chức năng và cũng đòi hỏi phải lập kế hoạch trước, và các lớp ngoại lệ tùy chỉnh mà các nhà xây dựng nắm bắt khung ngăn xếp hiện tại (trước khi ngoại lệ được ném thực sự); và, một khi bị bắt, cá thể lớp ngoại lệ được ném có thể được kiểm tra cho thông tin backtrace đã capture.

Nhưng điều đó không thực sự giúp tình hình hiện tại của bạn. Tôi sẽ đề nghị bạn kiểm tra tài liệu của trình biên dịch C++, như tôi đã gợi ý, và cũng điều tra khả năng của trình gỡ lỗi của bạn. Trình gỡ lỗi C++ sẽ cho phép bạn đặt điểm ngắt khi bất kỳ ngoại lệ nào bị ném và trước khi nó bị bắt, để bạn có thể kiểm tra ngăn xếp ngược thông qua trình gỡ rối, khi ngoại lệ xảy ra.

+0

Xin cảm ơn, tôi sẽ xem xét ngược lại. Điều đó có thể giúp tôi tránh được việc tìm kiếm nhị phân thông qua toàn bộ cơ sở mã! – Pace

+0

backtrace đã giúp (không bao giờ có thể nhận được các biểu tượng để giải quyết chính xác nhưng tôi đã có thể lưu chúng ra và sau đó cho chúng vào gdb để có được vị trí) và cuối cùng tôi có thể vấp ngã vào gốc của vấn đề. Cảm ơn. – Pace

+0

Câu trả lời này làm cho âm thanh như thể các thông điệp ngoại lệ thường được định nghĩa trong C++, nhưng điều này chỉ áp dụng cho lớp cơ sở 'std :: exception' và không áp dụng cho các lớp dẫn xuất như' std :: runtime_error', trong đó 'what' là đảm bảo trả về chuỗi bạn đã truyền trong hàm tạo. Ví dụ, §22.2.7/3 nói: * "Postconditions:' strcmp (what(), what_arg.c_str()) == 0' * ". IOW, nếu tôi tạo một 'std :: runtime_error x (" foo ")', thì 'cái gì' không được trả về' "std :: exception" '. –

10

này có thể là do hai yếu tố:

  1. Có người chỉ làm throw std::exception() nơi nào đó, mà không phải là rất hữu ích.

  2. Lớp học có nguồn gốc từ std::exception được sao chép thành std::exception. Đây là sự cố được gọi là Object Slicing.

Tôi vừa mắc lỗi thứ hai. Tôi đã có mã này:

try 
{ 
    // Some Boost stuff 
} 
catch (std::exception e) 
{ 
    cerr << e.what() << endl; 
} 

Bạn phải đảm bảo làm std::exception& e. Tôi biết bạn đã không phạm sai lầm này nhưng có thể một người khác đã làm thêm trong mã (hoặc ai đó đến đây từ Google).

+2

Cảm ơn, tôi đã bỏ lỡ &. – Tuntable

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