В настоящее время я работаю над системой отчетов об ошибках на основе исключений для приложений Windows MSVC++ (9.0) (т. Е. Структур исключения & типов/наследования, стека вызовов, сообщений об ошибках & и т. Д.).
Мой вопрос сейчас: как правильно сообщать & log out ошибка памяти?
При возникновении этой ошибки, например. как bad_alloc
, брошенный оператором new
, может быть много «функций» недоступно, в основном в отношении дальнейшего распределения памяти. Как правило, я передавал бы исключение в приложение, если оно было брошено в lib, а затем с помощью сообщений и файлов журнала ошибок для отчета и регистрации. Другой способ (в основном для служб) - использовать журнал событий Windows.
Основная проблема заключается в сборке сообщения об ошибке. Чтобы предоставить некоторую информацию об ошибке, я бы хотел задать статическое сообщение об ошибке (может быть строковым литералом, лучше содержать запись в файле сообщения, затем использовать FormatMessage) и включать некоторую информацию о времени выполнения, такую как стек вызовов.
Функции/методы, необходимые для такого использования либоC++/Windows: Как сообщить об исключении из памяти (bad_alloc)?
- СТЛ (
std::string, std::stringstream, std::ofstream
) - ЭЛТ (
swprintf_s, fwrite
) - или Win32 API (
StackWalk64, MessageBox, FormatMessage, ReportEvent, WriteFile
)
Помимо того, что документально на MSDN, все из них более (Win32) или менее (STL) закрыты в Windows, поэтому я не знаю, как они ведут себя при проблемах с низкой памятью.
Просто, чтобы доказать, что может быть проблемы, я написал тривиальное маленькое приложение провоцируя bad_alloc:
int main()
{
InitErrorReporter();
try
{
for(int i = 0; i < 0xFFFFFFFF; i++)
{
for(int j = 0; j < 0xFFFFFFFF; j++)
{
char* p = new char;
}
}
}catch(bad_alloc& e_b)
{
ReportError(e_b);
}
DeinitErrorReporter();
return 0;
}
Ран два экземпляра без отладчика прилагается (в конфигурации Release, VS 2008), но «ничего не произошло », то есть коды ошибок из ReportEvent или WriteFile, которые я использовал внутри отчета об ошибках. Затем запустили один экземпляр с одним отладочным отладчиком и попросили сообщить об ошибках один за другим, используя точку останова на линии ReportError. Это отлично работает для экземпляра с прикрепленным отладчиком (правильно зарегистрированный & зарегистрировал ошибку, даже используя проблемы LocalAlloc без проблем)! Но у Taskman было странное поведение, когда до выхода приложения много свободного места, я полагаю, когда вызывается исключение.
Пожалуйста, обратите внимание может быть более чем один процесс [править] и более чем один поток [/ править] отнимает много памяти, поэтому освободив предварительно выделяется куча пространство не является безопасным решением, чтобы избежать низкой среды памяти для процесс, который хочет сообщить об ошибке.
Заранее благодарю вас!
Вы считаете, что зарезервированный заранее зарезервированный блок памяти станет источником размещения когда система попадает в ситуацию с нехваткой памяти? Я только когда-либо использовал этот метод ради изящества из приложения, но операционные системы (OpenSolaris, Linux) делают что-то похожее, чтобы дать приложению достаточно времени для бесплатно или заменить низкоприоритетные ассигнования и изящно восстановить – Sniggerfardimungus
В настоящее время, Я использую некоторое пространство стека (переменные-члены, объявленные при вызове InitErrorReporter) для предоставления буферов для функций CRT/WinSDK. Но я не знаю, что они делают внутри, - см. Anser Alex Farber. – dyp
http://stackoverflow.com/questions/1308052/policy-with-catching-stdbad-alloc talk about something like – Chubsdad