В отладке, как узнать статистику (макс-мин, среднее, распределение ...) аргумента в повторяющихся вызовах функции? - PullRequest
0 голосов
/ 28 января 2019

Предположим, у меня есть функция void Myclass::func(x), и другой код выполняет тысячи обращений к ней.Теперь я хочу узнать некоторые характеристики аргумента x, например, среднее, максимальное, минимальное или даже график распределения.

void Myclass::func(int x) {
    while(foo.doFancyStuff(x)) {
        // ...
    }
}

Вот некоторые специальные методы, которые приходят мне в голову:

  1. Вывести каждое значение x в журнал.Затем используйте внешние инструменты / скрипты для их анализа.
    • Предостережения: смешано с другой информацией в журналах.Запись каждого значения x во внешний журнал или файл в файловой системе выполняется медленно.
  2. Определите глобальную переменную для хранения их и анализа в конце выполнения интереса.
    • Предостережения: глобальные переменные плохие.В будущем они запутаются.
  3. Храните их в классе Myclass.
    • Предостережения: не подлежащий повторному использованию код.Как насчет следующего раза, когда я хочу проанализировать Otherclass::doOtherStuff(y)?И плохая интеграция, потому что этот код статистики не должен быть связан с самим Myclass.

Есть ли какой-нибудь инструмент / библиотека для этого?Я использую Visual Studio в Windows, поэтому хотел бы получить ответ, пригодный для этой платформы.Также приветствуются кроссплатформенные инструменты.

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Вот пример использования скриптового API lldb (который также работает в Windows).Возьмите эту простую программу,

void func(int x) {}

int main(int, char **)
{
    for (int i = 0; i < 1000; ++i)
        func(i);
}

, которую вы можете проанализировать с помощью такого скрипта

import lldb
import os

fArgs = []

def analyzeFrame(frame, bpLocation, dict):
    variables = frame.GetVariables(True, False, False, False)
    x = variables.GetValueAtIndex(0).GetValueAsSigned()
    fArgs.append(x)
    return False

debugger = lldb.SBDebugger.Create()
debugger.SetAsync(False)
target = debugger.CreateTargetWithFileAndArch("pathToYourExecutable", "")

bp = target.BreakpointCreateByName("func", 4, lldb.SBFileSpecList(), lldb.SBFileSpecList())

bp.SetScriptCallbackFunction("analyzeFrame")

process = target.Launch(target.GetDebugger().GetListener(), [], [],
    None, None, None, os.getcwd(), 0, False, lldb.SBError())

print("max: {}".format(max(fArgs)))
print("min: {}".format(min(fArgs)))

. Вам нужно убедиться, что интерпретатор python находит модуль lldb.Путь можно увидеть, выполнив lldb -P в командной строке.

0 голосов
/ 28 января 2019

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

Для переносимого способа единственный вариант, который у вас есть, - это добавить кэшпредыдущие значения, затем в деструкторе вашего класса выведите нужную статистику.То, как вы кешируете данные, зависит от вас, вы можете спроектировать простой класс Stats<>, член класса, который вы хотите отслеживать, и обращаться к нему для хранения новых значений.Это было бы то, что я бы попробовал сначала, так как он портативный, почти чистый и многоразового использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...