Можно ли получить стек вызовов программно в VB6?

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

5 ответов


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

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

HTH


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

Private Function DoSomething(ByVal Arg as String)

    On Error GoTo Handler

    Dim ThisVar as String
    Dim ThatVar as Long

    ' Code here to implement DoSomething...

    Exit Function

Handler:
    Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description

End Function

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

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

Err.Raise PCLOADLETTER_ERRNUM, , "PC Load Letter error on Printer """ & PrinterName & """"

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


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


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

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

Sub MyRoutine
    (...)  ' Your code here
    call DoSomething (Var1, Var2, Var3, "MyRoutine")
    '                                       ^
    '     Present routine's name -----------+

    (...)  ' Your code here

End Sub


Public DoSomething (DoVar1, DoVar2, DoVar3, Optional Caller as string = "[unknown]")
    Debug.Print " DoSomething Routine Called. Caller = " & Caller

    ... ' (your code here)

End Sub

Не так элегантно, но это работает для меня.

С уважением, Максимум - Италия!--2-->


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

As Даррел указал, вы можете добавить что-то очень simlar с помощью MZTools и настройки шаблона. Это много работы и, вероятно, более эффективно, чем награда, но если вам очень сложно отслеживать ошибки, это может помочь).