我的C程序有以下问题:某处是堆栈溢出.尽管编译没有优化和调试符号,程序退出此输出(在Linux上的gdb内部或外部):
程序因信号SIGSEGV,分段故障而终止.该计划已不复存在.
我能够检测到这实际上是堆栈溢出的唯一方法是通过valgrind运行程序.有什么方法可以以某种方式强制操作系统转储调用堆栈跟踪,这将帮助我找到问题?
可悲的是,gdb也不允许我轻松地使用该程序.
我正在研究的项目使用jQuery.
我有一系列的Ajax调用,其中load()其他HTML片段反过来加载()其他片段.整件事令人困惑.我没有写代码.
有没有任何工具可以让我走一条callstack,这样我就能算出什么叫做方法?任何可以帮助我解决这个问题的浏览器工具?
解决方案:
最后这是因为在服务器端代码中注入了<script src ="...".您的建议确实有所帮助 - 它是这些的组合,并暂时设置Ajax来同步而不是异步,这有助于我追踪问题.
$.ajaxSetup({
async: false
});
Run Code Online (Sandbox Code Playgroud) 根据维基:
主叫方将返回地址压入堆栈,并且调用的子程序,当它完成,弹出返回地址关闭调用堆栈,并将控制转移到该地址.
来自Wiki的图片:

我不太明白这一点.说我有一个C程序如下:
#include <stdio.h>
int foo(int x)
{
return x+1;
}
void spam()
{
int a = 1; //local variable
int b = foo(a); //subroutine called
int c = b; //local variable
}
int main()
{
spam();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为调用堆栈应该类似于绘图,如下所示:
<None> means none local variables or params
_| parameters for foo() <int x> |_
top | local of spam() <int c> |
^ | return address of foo() |<---foo() called, when finishes, return here?
| | local …Run Code Online (Sandbox Code Playgroud) 我知道一个数组衰减到指针,如果一个声明
char things[8];
Run Code Online (Sandbox Code Playgroud)
然后在things其他地方使用,things是一个指向数组中第一个元素的指针.
另外,根据我的理解,如果有人宣称
char moreThings[8][8];
Run Code Online (Sandbox Code Playgroud)
那么moreThings它不是指向char的类型指针,而是类型为"指向char的指针数组",因为衰减只发生一次.
什么时候moreThings传递给一个函数(比如说原型void doThings(char thingsGoHere[8][8])实际上是什么进行了堆栈?
如果moreThings不是指针类型,那么这仍然是一个传递引用?我想我一直认为它moreThings仍然代表了多维数组的基地址.如果doThings接受输入thingsGoHere并将其传递给另一个函数会怎么样?
规则几乎是除非指定数组输入,const然后数组将始终可修改?
我知道类型检查的东西只发生在编译时,但我仍然对技术上作为一个引用传递的东西感到困惑(即只有当传递类型指针的参数时,或者指针数组是否为传递 - 参考也是?)
很抱歉这个问题在这个地方有点儿,但由于我很难理解这一点,很难说出一个精确的询问.
今天早上我回答了一个与StackoverflowException相关的问题.该人询问何时发生Stackoverflow异常
查看此链接在C#,C++和Java中导致堆栈溢出的最简单方法
所以我的问题是,有没有任何方法可以在程序中动态计算方法调用堆栈大小,然后在调用方法之前应用检查,该方法检查方法调用堆栈是否有空间来容纳它,以防止StackOverflowException.
因为我是一个java人,我正在寻找java,但也寻找与概念相关的解释,没有任何编程语言的限制.
如果我只是想做以下事情,看看有什么叫我,
var st = new StackTrace();
var callingMethod = st.GetFrame(1).GetMethod()
Run Code Online (Sandbox Code Playgroud)
获得特定框架会更便宜吗?
var sf = new StackFrame(1);
var callingMethod = sf.GetMethod()
Run Code Online (Sandbox Code Playgroud)
我测试了下面的代码,但我不确定我的方法是否合理.
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 100000; i++)
{
var method = new StackFrame(1, false);
}
sw.Stop();
Trace.WriteLine(sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (int i = 0; i < 100000; i++)
{
var method = new StackTrace().GetFrame(1);
}
sw.Stop();
Trace.WriteLine(sw.ElapsedMilliseconds);
// Results
// StackFrame: 850
// StackTrace: 1334
Run Code Online (Sandbox Code Playgroud)
我的方法(和结果)是否正确?
编辑
我会使用Caller Information属性,但是,我暂时停留在.NET 3.5中.
当我从gdb获取callstack时,我只获取函数名和源文件信息.
(gdb) f #0 main (argc=1, argv=0xbffff1d4) at main.c:5
我没有得到该函数所属的共享库或应用程序.
在Windows上,Windbg或Visual Studio将显示带有"myDll!myFunc"格式的callstack,该格式显示该函数属于哪个模块.
目前在gdb中,我使用"info address [function]"来获取函数符号的地址,然后使用"info share"手动查找函数在内存中的范围,以确定它所在的库.
无论如何直接看图书馆没有这个手动过程?
PHP提供了一些令人印象深刻的反省设施:get_defined_vars,get_defined_functions,get_defined_constants,debug_backtrace,和其他人.从本质上讲,它们提供了整个程序状态的视图:堆栈和堆.我想知道使用这些设施可以获得的程序状态的完整视图.
可以将作用域中的堆和所有已定义的变量建模为标记的有向图.例如,有可能写一些能给我Graphviz/DOT描述的东西吗?我正在想象类似于本文中关于"PHP如何管理变量"的图表,或者关于垃圾收集的PHP手册页面中的图表.
是否可以获得 Visual Studio 2019 调试器提供的等效堆栈跟踪。
例如,如果我在 Visual Studio 内的异步代码中设置断点,我会在“调用堆栈”窗口中看到以下堆栈跟踪
company.Common.dll!company.Common.Api.ResourcesDatabase.Lock() Line 58 C#
company.Common.dll!company.Common.Api.ResourcesDatabase.ResourcesDatabase(bool openAndCreateDB) Line 29 C#
company.Api.dll!company.Api.GlobalsDownloader.DownloadNewGlobals_UnderLock(System.Func<company.Common.Api.DTO.GlobalsType, System.Threading.Tasks.Task> reloadGlobals, company.Common.Api.DTO.GlobalsType globalsType) Line 124 C#
[Resuming Async Method]
[External Code]
[Async Call Stack]
[Async] company.Api.dll!company.Api.ApiService.VerifyLogin_UnderLock(bool skipInitTasks, System.Threading.CancellationToken ct) Line 1147 C#
[Async] company.Api.dll!company.Api.ApiService.VerifyLogin(System.Threading.CancellationToken ct) Line 955 C#
[Async] company.Api.dll!company.Api.ApiService.Init(System.Action initComplete, bool dontCheckForUpdates) Line 250 C#
[Async] company.Editor.exe!company.Editor.ViewModel.MainViewModel.Init() Line 524 C#
[Async] company.Editor.exe!company.Editor.ViewModel.MainViewModel.InitViewModel.AnonymousMethod__31_0() Line 331 C#
Run Code Online (Sandbox Code Playgroud)
如果我打电话new System.Diagnostics.StackTrace(1,true)我会得到以下信息
at company.Common.Api.ResourcesDatabase.Lock()
at company.Common.Api.ResourcesDatabase..ctor(Boolean openAndCreateDB)
at company.Api.GlobalsDownloader.<DownloadNewGlobals_UnderLock>d__6.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext(Object stateMachine) …Run Code Online (Sandbox Code Playgroud) 我正在阅读一本教科书,其中显示了基于 C 代码的汇编代码:
代码:
void echo()
{
char buf[8];
otherFunction(buf);
}
Run Code Online (Sandbox Code Playgroud)
汇编代码:
echo:
subq $24, %rsp //Allocate 24 bytes on stack, but why allocate 24 instead of 8 bytes?
movq %rsp, %rdi //Compute buf as %rsp
call otherFunction
Run Code Online (Sandbox Code Playgroud)
我不明白为什么堆栈指针%rsp会减少 24 个字节。我只将 8 个字节的缓冲区分配为char buf[8];,并且没有被调用者保存的寄存器压入堆栈,指令不应该是
subq $8, %rsp
Run Code Online (Sandbox Code Playgroud) callstack ×10
c ×4
c# ×2
gdb ×2
.net ×1
arrays ×1
assembly ×1
async-await ×1
benchmarking ×1
debugging ×1
gcc ×1
heap-dump ×1
java ×1
javascript ×1
jquery ×1
linux ×1
performance ×1
php ×1
pointers ×1
recursion ×1
stack ×1
stack-size ×1
stack-trace ×1
x86-64 ×1