Как извлечь отладочную информацию из катастрофического отказа

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

Насколько ваш пример componentDidUpdate, если то, что вы хотите сделать для разных реквизитов, является независимым, то вы можете использовать отдельные эффекты для каждого (то есть, несколько useEffect вызовов). Если вы хотите сделать точно , как в вашем примере (т.е. сделать что-то только для изменения companyName, если groupName также не изменилось, как указано вашим else if), тогда вы можете использовать ссылки для более сложных условий. Вы не должны не изменять мутировку ref во время рендеринга (всегда существует вероятность того, что рендер будет отброшен / переделан, если поддерживается параллельный режим), поэтому в примере используется последний эффект для обновления ссылок. В моем примере я использую ссылку, чтобы не выполнять эффектную работу на начальном рендере (см. Ответ Толле в на этот связанный вопрос ) и чтобы определить, изменился ли groupName при принятии решения о том, выполнять работу или нет. на основе изменения companyName.

const { useState, useEffect, useRef } = React;

const DerivedStateFromProps = ({ count }) => {
  const derivedCount = count > 100 ? 100 : count;

  return (
    
Derived from {count}: {derivedCount}{" "}
); }; const ComponentDidUpdate = ({ groupName, companyName }) => { const initialRender = useRef(true); const lastGroupName = useRef(groupName); useEffect( () => { if (!initialRender.current) { console.log("Do something when groupName changes", groupName); } }, [groupName] ); useEffect( () => { if (!initialRender.current) { console.log("Do something when companyName changes", companyName); } }, [companyName] ); useEffect( () => { if (!initialRender.current && groupName === lastGroupName.current) console.log( "Do something when companyName changes only if groupName didn't also change", companyName ); }, [companyName] ); useEffect( () => { // This effect is last so that these refs can be read accurately in all the other effects. initialRender.current = false; lastGroupName.current = groupName; }, [groupName] ); return null; }; function App() { const [count, setCount] = useState(98); const [groupName, setGroupName] = useState("initial groupName"); const [companyName, setCompanyName] = useState("initial companyName"); return (
groupName:{" "} setGroupName(event.target.value)} />
companyName:{" "} setCompanyName(event.target.value)} />
change both{" "} { const suffix = event.target.value; setGroupName(prev => prev + suffix); setCompanyName(prev => prev + suffix); }} />
); } const rootElement = document.getElementById("root"); ReactDOM.render(, rootElement);

Edit Derived state and componentDidUpdate

11
задан Eric Leschinski 26 October 2015 в 15:06
поделиться

9 ответов

Функция Stackwalk64 может использоваться для привязки трассировки стека в Windows.

Если вы собираетесь использовать эту функцию, вы должны обязательно скомпилировать свой код с FPO отключено - без символов StackWalk64 не сможет правильно обрабатывать кадры FPO.

Вы можете запустить некоторый код в процессе во время сбоя через __ try / __ except . ], вызвав SetUnhandledExceptionFilter. Это немного ненадежно, так как требует, чтобы код работал внутри аварийного процесса. В качестве альтернативы вы можете просто использовать встроенный отчет об ошибках Windows для сбора данных о сбоях. Это более надежно, поскольку не требует добавления кода, работающего внутри скомпрометированного, аварийного процесса. Единственная плата - получить сертификат для подписи кода, так как вы должны отправить подписанный двоичный файл в службу. https://sysdev.microsoft.com/en-US/Hardware/signup/ содержит более подробную информацию.

7
ответ дан 3 December 2019 в 05:59
поделиться

Вы можете использовать вызов Windows API MiniDumpWriteDump , если хотите накрутить свой собственный код. И Windows XP, и Vist автоматизируют этот процесс, и вы можете зарегистрироваться на https://winqual.microsoft.com , чтобы получить доступ к отчетам об ошибках.

Также посетите http: // kb.mozillazine.org/Breakpad и http://www.codeproject.com/KB/debug/crash_report.aspx для других решений.

3
ответ дан 3 December 2019 в 05:59
поделиться

Этот веб-сайт предоставляет довольно подробный обзор извлечения стека в Win32 после исключения C ++:

http://www.eptacom.net/pubblicazioni/pub_eng/except.html

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

2
ответ дан 3 December 2019 в 05:59
поделиться

Создать файл минидампа. Затем вы можете загрузить его в windbg или Visual Studio и проверить весь стек, в котором произошел сбой.

Вот , хорошее место для начала чтения.

2
ответ дан 3 December 2019 в 05:59
поделиться

Позвольте мне описать, как я обрабатываю сбои в моем приложении C ++ / WTL.

Сначала в основной функции я вызываю _set_se_translator и передайте функцию, которая вызовет исключение C ++ вместо использования исключений структурированных окон. Эта функция получает код ошибки, для которой вы можете получить сообщение об ошибке Windows через FormatMessage и аргумент PEXCEPTION_POINTERS, который можно использовать для записи минидампа (код здесь ). Вы также можете проверить код исключения на наличие определенных ошибок "распада", от которых вам следует избавиться,

2
ответ дан 3 December 2019 в 05:59
поделиться

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

Я опубликовал статью об этом несколько лет назад.

См. http://www.ddj.com/architect/185300443

2
ответ дан 3 December 2019 в 05:59
поделиться

Если вы хотите получить стек вызовов (плюс другую полезную информацию) для сбоя во время выполнения, в сборке выпуска даже на месте, тогда вам необходимо настроить Dr Watson (запустите DrWtsn32.exe). Если вы отметите опцию «генерировать аварийные дампы», когда приложение выйдет из строя, оно запишет файл мини-дампа по указанному пути (называемому user.dmp).

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

Получите сами windbg , откройте его и используйте опцию меню, чтобы «загрузить аварийный дамп». Как только он загрузится, вы можете набрать '~ # kp'

1
ответ дан 3 December 2019 в 05:59
поделиться

Вам нужно будет настроить структуру создания дампа в своем приложении, здесь - вот как это можно сделать.

Затем вы можете загрузить файл дампа в сервер для дальнейшего анализа с помощью анализаторов дампа, таких как windbg.

1
ответ дан 3 December 2019 в 05:59
поделиться

Вы можете использовать adplus для захвата аварийного вызова.

Можно загрузить и установить средства отладки для Windows.

Использование adplus упоминается здесь: Использование Adplus

Это приводит к полному сбою или зависание дампа. Как только у вас есть свалка, Windbg приходит на помощь. Сопоставьте правильные pdbs и символы, и все настроено на анализ дампа. Для начала используйте команду "!analyze -v"

0
ответ дан 3 December 2019 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: