Что такое дисбаланс стека? - PullRequest
2 голосов
/ 21 июля 2011

Прочитав эту статью F # против математики: Часть первая - Начало работы с BLAS и LAPACK Я наткнулся на термин stack imbalance в абзаце A Warning, Perhaps an Omen.

Я гуглил и искал по SO , но мог только найти людей, борющихся с дисбалансом стека и без объяснений вообще.

Бонусный вопрос: Влияет ли это только на f # или это общая проблема в C, C ++, Python, Java и т. Д .?

p.s. при необходимости измените теги вопроса

Ответы [ 2 ]

9 голосов
/ 21 июля 2011

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

В большинстве случаев стек является указателем памяти, в котором хранится адрес, на котором находится элемент управления.возобновится, когда текущий вызов функции будет возвращен вызывающей стороне.Существуют различные варианты этого, иногда аргументы функции также добавляются в стек, а также возвращаемое значение.Что здесь наиболее важно, так это то, что вызывающий абонент и вызываемый абонент должны договориться о том, как вернуть его в прежнее состояние после выхода вызываемого абонента.Это соглашение часто называют Соглашение о вызовах .

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

Вкл.Windows, есть несколько стандартных соглашений о вызовах, которые охватывают большую часть случаев вызова.

stdcall - Callee исправит стек при выходе.
fastcall - Потенциально нет необходимости фиксировать стек помимо адреса возврата, вместо этого регистры ЦПиспользуется для передачи аргументов.
cdecl - вызывающая сторона исправит стек после возврата вызванной функции.

Формальная ссылка доступна здесь: Соглашения о передаче и именовании аргументов @ MSDN

Это также представляет интерес: Список соглашений о вызовах X86 @ Wikipedia

В пределах данной области разработки это не является проблемой.Каждый язык обычно имеет соглашение, неявное для всех вызовов методов.C / C ++ использует то же соглашение для вызова вызовов C / C ++, Python для других вызовов Python и т. Д. При пересечении доменов это может стать проблемой, если один домен не использует то же самое, что и другой.Возможно, наиболее распространенная в Windows функция, экспортируемая с объявлениями стиля «C» (cdecl), может вызывать несбалансированный стек (или хуже) при вызове, как если бы она имела соглашение stdcall, которое является методом, распознаваемым вызовами WINAPI (система Windows).

5 голосов
/ 21 июля 2011

Мы только что видели это на днях (сортировка с помощью c # и c ++)

Я отсылаю вас к тексту со страницы MSDN :

Ассистент управляемой отладки pInvokeStackImbalance (MDA) активируется, когда CLR обнаруживает, что глубина стека после платформы вызов invoke не соответствует ожидаемой глубине стека, учитывая вызов соглашение, указанное в атрибуте DllImportAttribute, а также объявление параметров в управляемой подписи.

Я понимаю, что это для определенного предупреждения компилятора, но страница дает некоторую информацию о том, что такое дисбаланс стека, что его вызывает, каковы симптомы и как его устранить. Как сказал Даниэль, это обычно связано с тем, что подписи управляемого и неуправляемого не совпадают.

Надеюсь, это поможет.

...