解决“堆栈溢出”问题漏洞

发布于 08-14 05:21 字数 121 浏览 7 评论 0原文

我有一个用 Delphi W32 编写的应用程序,目前处于测试阶段。

在测试电脑上,使用几个小时后,它会随意踢出“堆栈溢出”消息。

如何捕获错误并查找原因?

我可以增加堆栈大小吗?

I have an application written in Delphi W32 that is in beta.

On the test PC, it haphazardly kicks out a 'stack overflow' message after a few hours of use.

How can I trap the error and find the cause?

Can I increase the Stack size?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

表情可笑2024-08-21 05:21:42

您应该减少链接器选项中的堆栈大小。然后在调试器下运行它,希望问题会出现,而不必等待两个小时。

You should REDUCE the stack size in linker options. Then run it under the debugger and hopefully the problem will show up without your having to wait two hours.

旧人九事2024-08-21 05:21:42

获取madExcept,它会告诉您故障发生时到底发生了什么。您将看到完整的堆栈,特别是它正在运行的地方。

Get madExcept and it will tell you exactly what is happening at the time of the fault. You'll see the full stack, and particularly where it is running away.

往事随风而去2024-08-21 05:21:42

我几乎想说:在调试器中运行它;^)

我过去所做的就是在每个方法中添加一个进入和离开日志功能。通过正确的缩进,我可以在日志中跟踪调用路径。

当发生堆栈溢出时,它确实会在日志中可见,因为缩进级别应该是最高的,

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

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

      logMethodLeave("someMethod");

 }

记录器将跟踪当前的日志深度和日志内容,如下所示:

 >someMethod
   something
 <someMethod

I'd almost say: run it in the debugger ;^)

What I used to do is add a enter and leave log function in every method. With the proper indentation I could trace in the log the callpath.

When a stackoverflow would occur it would really be visible in the log since the indentation level should be through the roof

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

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

      logMethodLeave("someMethod");

 }

the logger would keep track of current logdepth and log stuff like this:

 >someMethod
   something
 <someMethod
冰之心2024-08-21 05:21:42

测试机上安装IDE了吗?如果是这样,请尝试从 IDE 中重现问题。发生堆栈溢出时,查看调用堆栈(View->Debug Windows->Call Stack)。它可能会多次调用相同的函数,如下所示:

FunctionA
FunctionB
FunctionA
FunctionB
FunctionA
FunctionB
...

如果您看到这一点,那么您就知道这些函数正在相互调用而没有结束。

如果您没有在测试机上安装IDE,那么您仍然可以通过远程调试来完成此操作。如果您提供有关您的情况的更多信息,我们也许能够提供更多帮助。

具体来说,了解以下内容可能会有所帮助:

  • 您可以复制它吗?
  • 测试上是否安装了IDE
    机器?
  • 德尔福是什么版本的?

Do you have the IDE installed on the test machine? If so, try to reproduce the problem from within the IDE. When the stack overflow occurs, look at the Call Stack (View->Debug Windows->Call Stack). It will probably have the same function being called many times, like this:

FunctionA
FunctionB
FunctionA
FunctionB
FunctionA
FunctionB
...

If you see that, then you know that these functions are calling each other without ever concluding.

If you don't have the IDE installed on the test machine, then you can still do this via remote debugging. If you provide a little more information about your scenario we may be able to help more.

Specifically it might be helpful to know:

  • Can you reproduce it?
  • Is the IDE installed on the test
    machine?
  • What version of Delphi?
岁月静好2024-08-21 05:21:42

您可以使用项目链接器选项或 $M 编译器指令来增加堆栈大小,但我认为这不会解决问题,除非堆栈非常小。

如果您在调试器中运行应用程序,它最终会因异常而中断。

You can increase the stack size using the project linker options or the $M compiler directive, but I don't think it wil solve the problem unles the stack is really small.

If you run the application in the debugger, it will break at the exception eventually.

汐鸠2024-08-21 05:21:42

如果您使用线程(不是主线程:sock 连接)和主线程,那么它们共享相同的堆栈。这样解决:只需为每个连接创建一个具有自己的堆栈的线程。

问题>每次调用你都会调用帧的堆栈(共享的一个很大的问题)
例如,您调用 proc aa(a,b:integer) 例如,始终调用相同的函数或不同的函数;

你有一个正在运行的套接字线程,并且 onconnect 你调用 proc a;并持续做一些需要 5 秒的事情。

如果有人在 on connect 关闭连接之前连接(释放堆栈)。
您有 2 个已连接的客户端(2 个差异堆栈帧,每个堆栈帧都有不同的数据)

堆栈

推入a,b(整数);值 5,10 - 来自 1 个连接

推入a,b(整数);值 7,3 - 来自 2 个连接

如果 onconnect 调用函数 a(5,10) 并持续执行某操作约 5 秒,则从 2 conn 开始。
并且有人再次连接到服务器套接字,它再次调用连接。

堆栈保留了第一个调用帧,但没有脱离过程。所以没有从 (5,10) 中弹出 a,b

它比这更复杂,如果你再次调用 proc 那么它将覆盖 2 帧上的数据(2 个连接的本地 proc 变量),所以当 2 个连接从堆栈获取数据时肯定已经被其他信息覆盖了。所以它会做出不正确的行为。

当第一个连接断开时,将弹出 a,b,但会弹出 7,3(来自第二个连接),而不是它保存的 5,10。因此它不会立即发生堆栈溢出,而是稍后随着程序运行和堆栈释放错误,您最终会得到一个 $FFFFFFFF $SP 堆栈。所以当你调用一个函数时,它会尝试$FFFFFFAA,所以它比你的堆栈大,例如:$M 65536,而不是$FFFFFFAA那样的4GB >。

If you are using a thread(not main ex:sock connection) and main thread so they share the same stack. Solve this way :just create a thread with its own stack for each connection.

Problem > each call you do it call stack for frame (the shared one so big problem)
example you call proc aa(a,b:integer) for example on calling always the same function or different one ;

You have a socket thread running, and onconnect you call proc a; and stays doing something it take 5 secs.

if some one connects before the on connect close connection (release stack).
You have the 2 connected clients (2 diff stack frames with each different data)

stack

push a,b (integer); Values 5,10 - from 1 conn

push a,b (integer); Values 7,3 - from 2 conn

if the onconnect call the functions a(5,10) and stays doing something for about 5 sec.
and some one connect to the server socket again it call on connect again.

The stack olds the first call frame yet didn't went out of proc. So didn't pop a,b from (5,10)

It is more complex than this if you proc call again then it will override data on the 2 frame (local proc variable of 2 connection) so when 2 connection get data from stack is already overridden by other info for sure. so it will do incorrect behavior.

When first connection is down will pop a,b but 7,3 (from second connection) and not the 5,10 it saved. so it will stack overflow not on the moment but later with the program running and stack release errors you'll get eventually a $FFFFFFFF $SP stack. so it will try to $FFFFFFAA when you call a function so is bigger than ya stack ex: $M 65536 and not 4 gigabytes as $FFFFFFAA.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文