Super Robust как chrome C++ и портативный - советы - помощь - комментарии

Мы производим переносимый код (win+macOs) и ищем, как сделать код более устойчивым, так как он часто вылетает... (обычно переполнения или плохая инициализация):-(

Я читал, что Google Chrome использует процесс для каждой вкладки, поэтому, если что-то пойдет не так, программа не завершится аварийно, только эта вкладка. Я думаю, что это довольно опрятно, так что я могу попробовать!

Так что мне было интересно, есть ли у кого-нибудь какие-нибудь советы, помощь, список для чтения, комментарии или что-то, что может помочь мне создать больше кода Ruby C++ (портативный всегда лучше).

В той же теме мне также было интересно, есть ли переносимая библиотека для процессов (например, boost)?

Ну большое спасибо.

12 ответов

Решение

Я разработал множество мультиплатформенных приложений на C++ (самые большие из которых составляют 1,5 млн строк кода и работают на 7 платформах - AIX, HP-UX PA-RISC, HP-UX Itanium, Solaris, Linux, Windows, OS X), У вас на самом деле есть две совершенно разные проблемы в вашем посте.

  1. Неустойчивость. Ваш код не стабилен. Почини это.

    • Используйте юнит-тесты, чтобы найти логические проблемы, прежде чем они убьют вас.
    • Используйте отладчики, чтобы узнать, что вызывает сбои, если это не очевидно.
    • Используйте boost и подобные библиотеки. В частности, типы указателей помогут вам избежать утечек памяти.
  2. Кроссплатформенное кодирование.

    • Опять же, используйте библиотеки, которые предназначены для этого, когда это возможно. Особенно для любых битов GUI.
    • Максимально используйте стандарты (например, ANSI против gcc/MSVC, потоки POSIX против моделей потоков, специфичных для Unix, и т. Д.), Насколько это возможно, даже если это требует немного больше работы. Минимизация кода для вашей платформы означает меньшую общую работу и меньше API для изучения.
    • Изолировать, изолировать, изолировать. По возможности избегайте встроенных #ifdefs для разных платформ. Вместо этого, вставьте специфичный для платформы код в свой собственный заголовок / источник / класс и используйте вашу систему сборки и #include для получения правильного кода. Это помогает сохранить код чистым и читаемым.
    • Используйте целочисленные типы C99, если это вообще возможно, вместо "long", "int", "short" и т. Д. - в противном случае он укусит вас при переходе с 32-разрядной платформы на 64-разрядную, и значения long внезапно изменятся от 4 байтов до 8 байтов. И если это когда-либо будет записано в сеть / диск / и т. Д., Вы столкнетесь с несовместимостью между платформами.

Лично я сначала стабилизировал код (без добавления каких-либо дополнительных функций), а затем занялся кроссплатформенными проблемами, но это зависит от вас. Обратите внимание, что Visual Studio имеет отличный отладчик (упомянутая выше кодовая база была портирована на Windows именно по этой причине).

Ответ Chrome больше о смягчении сбоев, а не о качестве кода. Делать то, что делает Chrome, значит признать поражение.

  1. Лучшее обеспечение качества - это больше, чем просто программист, тестирующий свою работу.
  2. Модульное тестирование
  3. Регрессионное тестирование
  4. Читайте о лучших практиках, которые используют другие компании.

Если говорить прямо, если ваше программное обеспечение часто выходит из строя из-за переполнения и неправильной инициализации, то у вас есть очень простая проблема качества программирования, которую нелегко решить. Это звучит хэш и значит, это не мое намерение. Я хочу сказать, что проблема с плохим кодом должна быть вашей главной заботой (что, я уверен, так и есть). Такие вещи, как Chrome или либеральное использование обработки исключений для выявления недостатков программы, только отвлекают вас от реальной проблемы.

" Эффективный C++ и более эффективный C++" Скотта Мейерса очень хорош, и его приятно читать.

Кодекс Стива Макконнелла является любимым у многих, включая Джеффа Этвуда.

Библиотеки Boost, вероятно, являются отличным выбором. Один проект, где я работаю, использует их. Я сам использовал только потоки WIN32.

Вы не упоминаете, каков целевой проект; наличие процесса на вкладке вовсе не обязательно означает более "надежный" код. Вы должны стремиться писать надежный код с тестами независимо от переносимости - просто прочитайте о написании хорошего кода на C++:)

Что касается раздела о переносимости, убедитесь, что вы тестируете на обеих платформах с первого дня, и убедитесь, что новый код не написан, пока не решены проблемы, специфичные для платформы.

Я согласен с Торлаком.

Плохая инициализация или переполнения являются признаками низкого качества кода.

Google сделал это таким образом, потому что иногда не было никакого способа контролировать код, который выполнялся на странице (из-за неисправных плагинов и т. Д.). Так что, если вы используете плагины низкого качества (это бывает), возможно, решение Google подойдет вам.

Но программа без плагинов, которая часто вылетает, просто плохо написана, или очень, очень сложна, или очень старая (и не требует много времени на обслуживание). Вы должны остановить разработку и расследовать каждый сбой. В Windows скомпилируйте модули с PDB (программными базами данных) и при каждом сбое подключайте к ним отладчик.

Вы также должны добавить внутренние тесты. Избегайте шаблона:

doSomethingBad(T * t)
{
   if(t == NULL) return ;

   // do the processing.
}

Это очень плохой дизайн, потому что ошибка есть, и вы просто избежите ее, на этот раз. Но следующая функция без этой охраны потерпит крах. Лучше разбиться раньше, чтобы быть ближе к ошибке.

Вместо этого в Windows (должен быть похожий API в MacOS)

doSomethingBad(T * t)
{
   if(t == NULL) ::DebugBreak() ; // it will call the debugger

   // do the processing.
}

(не используйте этот код напрямую... Поместите его в определение, чтобы избежать его доставки клиенту...) Вы можете выбрать подходящий API ошибок (исключения, DebugBreak, assert и т. д.), но использовать его чтобы остановить момент, когда код знает, что что-то не так.

По возможности избегайте C API. Используйте идиомы C++ (RAII и т. Д.) И библиотеки.

Так далее..

PS: Если вы используете исключения (что является хорошим выбором), не скрывайте их в улове. Вы только усугубите свою проблему, потому что ошибка есть, но программа попытается продолжить работу и, возможно, будет иногда аварийно завершать работу и повреждать все, к чему прикасается за это время.

Вы действительно, действительно, не хотите делать то, что делает Chrome, для этого требуется менеджер процессов, который, вероятно, излишне излишним для того, что вы хотите.

Вы должны исследовать использование умных указателей из Boost или другого инструмента, который обеспечит подсчет ссылок или сборку мусора для C++.

В качестве альтернативы, если вы часто зависаете, возможно, вы захотите написать не критически важные для вашего приложения части вашего приложения на языке сценариев с привязками C++.

Я бы порекомендовал вам скомпилировать версию для Linux и запустить ее под Valgrind.

Valgrind будет отслеживать утечки памяти, неинициализированные чтения памяти и многие другие проблемы с кодом. Я очень рекомендую это.

Помимо написания более стабильного кода, вот одна идея, которая отвечает на ваш вопрос.

Используете ли вы процессы или потоки. Вы можете написать небольшую / простую сторожевую программу. Затем другие ваши программы регистрируются в этом сторожевом таймере. Если какой-либо процесс умирает или поток умирает, он может быть перезапущен сторожевым таймером. Конечно, вы захотите провести некоторый тест, чтобы убедиться, что вы не перезапускаете один и тот же глючный поток. то есть: перезапустите его 5 раз, затем после 5-го закройте всю программу и войдите в файл / syslog.

После более чем 15 лет разработки Windows я недавно написал свое первое кроссплатформенное приложение на C++ (Windows/Linux). Вот как:

  • СТЛ
  • Увеличение. В частности, файловая система и библиотеки потоков.
  • Пользовательский интерфейс на основе браузера. Приложение "делает" HTTP с пользовательским интерфейсом, состоящим из XHTML/CSS/JavaScript (стиль Ajax). Эти ресурсы встроены в код сервера и при необходимости передаются в браузер.
  • Обильное юнит-тестирование. Не совсем TDD, но близко. Это фактически изменило способ, которым я развиваюсь.

Я использовал NetBeans C++ для сборки Linux, и у меня был полный порт Linux.

Вы всегда можете добавить обработку исключений в свою программу, чтобы улавливать подобные ошибки и игнорировать их (хотя детали зависят от платформы) ... но это в значительной степени обоюдоострый меч. Вместо этого подумайте о том, чтобы программа перехватила исключения и создала файлы дампа для анализа.

Если ваша программа вела себя неожиданно, что вы знаете о своем внутреннем состоянии? Может быть, аварийная процедура / поток повредила какую-то ключевую структуру данных? Может быть, если вы поймете ошибку и попытаетесь продолжить, пользователь сохранит все, над чем он работает, и зафиксирует повреждение на диске?

Создайте свое приложение с помощью символов отладки, затем добавьте обработчик исключений или настройте Dr Watson для создания аварийных дампов (запустите drwtsn32.exe /i, чтобы установить его в качестве отладчика, без / i, чтобы открыть диалоговое окно конфигурации). Когда ваше приложение дает сбой, вы можете проверить, где оно пошло не так в windbg или visual studio, просмотрев стек вызовов и переменные.

Google для сервера символов для получения дополнительной информации.

Очевидно, что вы можете использовать обработку исключений, чтобы сделать ее более надежной и использовать умные указатели, но исправление ошибок - это лучшее.

Создайте его с мыслью, что единственный способ выйти из программы - аварийное завершение программы, и что она может произойти сбой в любое время. Когда вы строите это таким образом, сбой никогда / почти никогда не потеряет никаких данных. Я прочитал статью об этом год или два назад. К сожалению, у меня нет ссылки на это.

Объедините это с каким-нибудь аварийным дампом и получите его по электронной почте, чтобы вы могли решить проблему.

Другие вопросы по тегам