Tôi đang viết thư viện mà tôi muốn di chuyển. Vì vậy, nó không nên phụ thuộc vào glibc hoặc phần mở rộng của Microsoft hoặc bất cứ điều gì khác mà không phải là trong tiêu chuẩn. Tôi có một hệ thống phân cấp tốt đẹp của các lớp học bắt nguồn từ std :: exception mà tôi sử dụng để xử lý các lỗi trong logic và đầu vào. Biết rằng một loại ngoại lệ cụ thể được ném vào một tệp cụ thể và số dòng là hữu ích, nhưng biết cách thực hiện ở đó sẽ có khả năng có giá trị hơn rất nhiều, vì vậy tôi đã tìm cách thu thập dấu vết ngăn xếp.Dấu vết ngăn xếp C++ di động khi ngoại lệ
Tôi biết rằng dữ liệu này có sẵn khi xây dựng chống lại glibc sử dụng các hàm trong execinfo.h (xem question 76822) và thông qua giao diện StackWalk trong triển khai C++ của Microsoft (xem question 126450), nhưng tôi rất muốn tránh bất cứ điều gì đó không phải là di động.
Tôi đã nghĩ đến việc thực hiện chức năng này bản thân mình theo hình thức này:
class myException : public std::exception
{
public:
...
void AddCall(std::string s)
{ m_vCallStack.push_back(s); }
std::string ToStr() const
{
std::string l_sRet = "";
...
l_sRet += "Call stack:\n";
for(int i = 0; i < m_vCallStack.size(); i++)
l_sRet += " " + m_vCallStack[i] + "\n";
...
return l_sRet;
}
private:
...
std::vector<std::string> m_vCallStack;
};
ret_type some_function(param_1, param_2, param_3)
{
try
{
...
}
catch(myException e)
{
e.AddCall("some_function(" + param_1 + ", " + param_2 + ", " + param_3 + ")");
throw e;
}
}
int main(int argc, char * argv[])
{
try
{
...
}
catch (myException e)
{
std::cerr << "Caught exception: \n" << e.ToStr();
return 1;
}
return 0;
}
Đây có phải là một ý tưởng khủng khiếp? Nó sẽ có nghĩa là rất nhiều công việc thêm thử/bắt khối để mọi chức năng, nhưng tôi có thể sống với điều đó. Nó sẽ không hoạt động khi nguyên nhân của ngoại lệ là lỗi bộ nhớ hoặc thiếu bộ nhớ, nhưng tại thời điểm đó bạn đang khá nhiều hơi say anyway. Nó có thể cung cấp thông tin gây hiểu lầm nếu một số chức năng trong ngăn xếp không bắt ngoại lệ, thêm chính họ vào danh sách và truy lại, nhưng ít nhất tôi cũng có thể đảm bảo rằng tất cả các chức năng thư viện của tôi đều làm như vậy. Không giống như một dấu vết ngăn xếp "thực" tôi sẽ không nhận được số dòng trong các chức năng gọi điện thoại, nhưng ít nhất tôi sẽ có một cái gì đó.
Mối quan tâm chính của tôi là khả năng điều này sẽ làm chậm lại ngay cả khi không có trường hợp ngoại lệ nào thực sự bị ném. Tất cả các khối try/catch này có yêu cầu thiết lập bổ sung và xé rách trên mỗi lời gọi hàm hay không bằng cách nào đó được xử lý tại thời gian biên dịch? Hoặc có những vấn đề khác mà tôi đã không xem xét?
Kiểm tra http://www.gotw.ca/gotw/047.htm của Herb Sutter đối với một góc nhìn khác. – AJG85