Я хотел бы исследовать первые 4 байта памяти пустоты-указатель который указует, чтобы увидеть, если это адрес действующих виртуальных таблиц.
Вы можете это сделать, но у вас нет никаких гарантий, что это будет работать. Я даже не знаю, будет ли void * указывать на vtable. В прошлый раз, когда я смотрел на это (5+ лет назад), я считаю, что некоторый компилятор сохранил указатель vtable до адрес, на который указывает экземпляр *.
Я знаю, что это платформа, может быть, даже компилятором конкретной версии,
Он также может быть компилятором варианты speciffic, в зависимости от того, какие оптимизации вы используете, и так далее.
, но это может помочь мне в продвижении приложения вперед, и избавиться от всех недействительных указателей в течение ограниченного периода времени (скажем, 3 лет).
Это единственный вариант, который вы можете увидеть для перемещения приложения вперед? Вы считали других? не
Есть ли способ, чтобы получить список всех виртуальных таблиц в приложении,
Нет :(
или способ проверить, является ли указатель указывает на действительный vtable,
Нет стандартного способа. Что вы можете сделать, так это открыть некоторые указатели на классы в вашем любимом debu gger (или отложите память на байты и запишите ее в файл), и сравните ее и посмотрите, имеет ли смысл. Тем не менее, у вас нет гарантий, что никакие ваши данные (или другие указатели в приложении) не будут выглядеть достаточно похожими (при использовании в виде байтов), чтобы запутать любой код, который вам нравится.
и является ли этот экземпляр, указывающий на на виртуальные таблицы наследует от известного базового класса ?
Нет снова.
Вот несколько вопросов (возможно, вы уже их рассмотрели). Ответы на них могут дать вам больше возможностей или могут дать нам другие идеи:
, насколько велика кодовая база? Возможно ли внедрить глобальные изменения или это функциональность для распространения?
вы относитесь все указатели равномерно (то есть: есть ли общие точки в исходном коде, где можно подключить и добавить свои собственные метаданные)
, что вы можете изменить в исходном коде? (Если у вас есть доступ к вашим подпрограммам распределения памяти или вы можете подключить свои собственные, например, вы можете подключить свои собственные метаданные).
Если разные типы данных отлиты от void * в различных частях вашего кода, как вы позже определяете, что находится в этих указателях? Можете ли вы использовать код, который различает void *, чтобы решить, являются ли они классами или нет?
Предоставляет ли ваша кодовая база методологии рефакторинга? (Рефакторинг в малых итерациях, путь подключения альтернативных реализаций для частей коды, того удаления первоначальной реализации и тестирования всего)
Редактировать (предлагаемое решение):
Выполните следующие действия:
определяют метаданные (базовый) класс
заменить вашу подпрограммы распределения памяти с пользовательскими, которые относятся только к стандартным/старым процедурам (и убедитесь, что ваш код по-прежнему работает с пользовательскими подпрограммами).
при каждом размещении, укажите the requested size + sizeof(Metadata*)
(и убедитесь, что код по-прежнему работает).
заменить первыеsizeof(Metadata*)
байт вашего выделения со стандартной последовательности байтов, которые вы можете легко проверить для (я неравнодушен к 0xDEADBEEF: D). Затем верните [allocated address] + sizeof(Metadata*)
в приложение. При освобождении возьмите полученный указатель, уменьшите его на sizeof (метаданные *), затем вызовите системную/предыдущую процедуру для выполнения освобождения. Теперь у у вас есть дополнительный буфер, выделенный в вашем коде, в частности для метаданных по каждому распределению.
В случаях, когда вы заинтересованы в наличии метаданных, создайте/получите указатель класса метаданных, а затем установите его в зоне 0xDEADBEEF. Когда вам нужно проверить метаданные, reinterpret_cast<Metadata*>([your void* here])
, уменьшите его, а затем проверьте, равно ли значение указателя 0xDEADBEEF (без метаданных) или что-то еще.
Обратите внимание, что этот код должен быть только там для рефакторинга - для производства кода это очень медленный процесс, к ошибкам и вообще другие плохие вещи, которые вы не хотите, чтобы ваш код продукции будет. Я бы сделал весь этот код зависимым от некоторого REFACTORING_SUPPORT_ENABLED
макроса, который никогда не позволил бы вашему классу метаданных видеть свет производственного выпуска (за исключением, возможно, тестирования сборки).
По всем вашим вопросам: да, я могу реорганизовать и многое изменить. Но я действительно искал трюки, поэтому части программного обеспечения могут работать с указателями void (во время перехода) или способами поиска проблем (в случае, если некоторые указатели void были «забыты»). – Patrick
См. Мое изменение выше для решения. – utnapistim
Отличная идея. К счастью, у меня даже есть опыт работы с пользовательскими процедурами распределения, поэтому это должно быть довольно легко реализовать. Благодарю. – Patrick