Запуск ошибки «переполнение стека» - PullRequest
5 голосов
/ 03 декабря 2009

У меня есть приложение, написанное на Delphi W32, которое находится в бета-версии.

На тестовом ПК он случайно выводит сообщение «переполнение стека» после нескольких часов использования.

Как я могу перехватить ошибку и найти причину?

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

Ответы [ 6 ]

15 голосов
/ 03 декабря 2009

Вы должны СОКРАТИТЬ размер стека в опциях компоновщика. Затем запустите его под отладчиком, и, надеюсь, проблема обнаружится без необходимости ждать два часа.

13 голосов
/ 03 декабря 2009

Получите madExcept и он точно скажет вам, что происходит во время ошибки. Вы увидите полный стек, и особенно там, где он убегает.

6 голосов
/ 03 декабря 2009

Я бы почти сказал: запустите его в отладчике; ^)

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

Когда произойдет переполнение стека, оно действительно будет видно в журнале, поскольку уровень отступа должен быть выше крыши

 void someMethod()
 {
      logMethodEnter("someMethod");

      ... do stuff...
      log("something")
      ... do stuff...

      logMethodLeave("someMethod");

 }

регистратор будет отслеживать текущую logdepth и регистрировать такие вещи:

 >someMethod
   something
 <someMethod
2 голосов
/ 03 декабря 2009

У вас установлена ​​тестовая среда на тестовом компьютере? Если это так, попробуйте воспроизвести проблему из среды IDE. Когда происходит переполнение стека, посмотрите на стек вызовов (View-> Debug Windows-> Call Stack). Вероятно, одна и та же функция будет вызываться много раз, например:

FunctionA
FunctionB
FunctionA
FunctionB
FunctionA
FunctionB
...

Если вы видите это, то вы знаете, что эти функции вызывают друг друга без какого-либо завершения.

Если на тестовом компьютере не установлена ​​среда IDE, это можно сделать с помощью удаленной отладки. Если вы предоставите немного больше информации о вашем сценарии, мы сможем помочь вам больше.

В частности, может быть полезно знать:

  • Можете ли вы воспроизвести его?
  • Установлена ​​ли IDE на тесте машина
  • Какая версия Delphi?
0 голосов
/ 29 апреля 2010

Если вы используете поток (не main, например: sock connection) и основной поток, поэтому они используют один и тот же стек. Решите так: просто создайте поток со своим стеком для каждого соединения.

Проблема> каждый вызов, который вы делаете, вызывает стек для фрейма (общая проблема очень большая) Например, вы вызываете proc aa (a, b: integer), например, при вызове всегда одной и той же функции или другой;

У вас запущен поток сокетов, и onconnect вы вызываете proc a; и продолжает делать что-то, это занимает 5 секунд.

, если кто-то подключается до соединения «закрыто» (выпуск стека). У вас есть 2 подключенных клиента (2 кадра стека различий с различными данными)

стек

push a, b (целое число); Значения 5,10 - от 1 конн

push a, b (целое число); Значения 7,3 - от 2 кон

если onconnect вызывает функции a (5,10) и продолжает делать что-то около 5 секунд. и кто-то снова подключается к серверному сокету, он снова вызывает соединение.

Стек устарел первый кадр вызова, но еще не вышел из proc. Так что не поп а, б из (5,10)

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

Когда первое соединение не работает, выскочит a, b, но 7,3 (из второго соединения), а не 5,10, которые он сохранил. поэтому переполнение стека произойдет не в данный момент, а позже, при запуске программы и ошибках выпуска стека, в итоге вы получите стек $FFFFFFFF $SP. поэтому он попытается $FFFFFFAA, когда вы вызываете функцию, которая больше, чем у вас, например: $M 65536, а не 4 гигабайта, как $FFFFFFAA.

0 голосов
/ 03 декабря 2009

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

Если вы запустите приложение в отладчике, оно, в конце концов, прекратит работу с исключением.

...