Вопрос по runtime, callstack, vb6 – Можно ли программно получить стек вызовов в VB6?
====================================================================================

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

Вы должны сделать это трудным путем, но это еще не все**that** тяжело ... Серьезно, после того как вы написали шаблон один раз, он быстро копирует / вставляет / модифицирует, чтобы сопоставить имя функции в операторе Err.Raise с фактическим именем функции.

Когда у вас есть вложенные вызовы, это раскручивается, когда каждая подпрограмма достигает своего обработчика и добавляет свое имя в описание ошибки. В функции верхнего уровня вы получаете «стек вызовов» показывает список вызванных подпрограмм, номер ошибки и описание ошибки, которая фактически произошла. Это не идеально, потому что вы не получаете номера строк, но я обнаружил, что они вам обычно не нужны, чтобы найти путь к проблеме. (И если вам действительно нужны номера строк, вы можете поместить их в функцию и ссылаться на них в операторе Err.Raise, используя переменную Erl. Без номеров строк это просто возвращает 0.)

Также обратите внимание, что внутри самой функции вы можете выдавать свои собственные ошибки со значениями интересных переменных в сообщении, например, так:

(Подсветка синтаксиса выглядит превью в превью ... Интересно, как она будет выглядеть после публикации?)



Как говорили другие люди (много лет назад, я вижу ... но так много людей все еще используют VB6! :)), я думаю, что программным способом невозможно получить стек вызовов, если вы не используете какой-либо сторонний инструмент ,

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

Может быть, не так элегантно, но у меня это сработало.

С Уважением,
Макс - Италия



Трудный, ручной способ - в значительной степени единственный путь. Если вы проверите[этот](https://stackoverflow.com/questions/116289/what-is-the-better-way-to-handle-errors-in-vb6) вопрос, кто-то предложил инструмент под названием MZTools, который сделает большую часть тяжелой работы за вас.



Compuware (или это был Numega в то время) DevStudio для Visual Basic 6 использовал для этого. Способ заключался в добавлении инструментария к каждому вызову, который вызывал очень маленький фрагмент кода, добавляемый в стек кода. При любой ошибке он сбрасывал этот стек вызовов, а затем делал такие вещи, как почта или отправка на веб-сервер всей отладочной информации. Добавление и удаление инструментов было потенциально смертельной операцией (особенно тогда, когда мы использовали VSS в качестве нашего источника контроля), но если это работало, это работало хорошо.

Как[Даррел указал](https://stackoverflow.com/questions/127645/is-it-possible-to-retrieve-the-call-stack-programmatically-in-vb6#128285)Вы можете добавить что-то очень простое, используя MZTools и настроив шаблон. Это очень много работает и, вероятно, более эффективно, чем вознаграждение, но если вам очень трудно отследить ошибки, это может помочь).



Я уверен, что вы должны сделать это трудным путем. На моей предыдущей работе у нас был очень элегантный процесс обработки ошибок для VB6 с компонентами DCOM. Тем не менее, это был очень избыточный код, который должен был быть добавлен к каждому методу, настолько, что у нас были собственные инструменты, чтобы вставить все это для вас.

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

НТН