Можно ли программно получить стек вызовов в VB6? - PullRequest
13 голосов
/ 24 сентября 2008

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

Ответы [ 5 ]

11 голосов
/ 16 октября 2008

Вы должны сделать это трудным путем, но это не совсем все , что трудно ... Серьезно, если вы написали шаблон один раз, это быстрая копия / paste / modify для сопоставления имени функции в операторе 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 & """"

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

9 голосов
/ 24 сентября 2008

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

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

НТН

3 голосов
/ 24 сентября 2008

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

1 голос
/ 25 ноября 2013

Как говорили другие люди (много лет назад, я вижу ... но так много людей все еще используют 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

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

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

0 голосов
/ 13 октября 2008

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

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

...