我们正在围绕LLVM库进行研究,我们发现IR库有时可以访问堆栈最多29个方法。
有时候,当我在iOS框架中看到一些崩溃时,我也会观察到很深的呼叫堆栈。
我的问题是,我们是否可以推释一下,设计的代码是否有问题,该代码将自己称为如此之大的深度。
这是一个示例:
/usr/local/LLVM/llvm/unittests/IR/AttributesTest.cpp:54
/usr/local/LLVM/llvm/lib/IR/LLVMContext.cpp:162
/usr/local/LLVM/llvm/lib/IR/LLVMContext.cpp:162
/usr/local/LLVM/llvm/lib/IR/LLVMContextImpl.cpp:54
/usr/local/LLVM/llvm/lib/IR/LLVMContextImpl.cpp:59
/usr/local/LLVM/llvm/lib/IR/Module.cpp:60
/usr/local/LLVM/llvm/lib/IR/Module.cpp:62
/usr/local/LLVM/llvm/lib/IR/Module.cpp:456
/usr/local/LLVM/llvm/lib/IR/Function.cpp:350
/usr/local/LLVM/llvm/lib/IR/BasicBlock.cpp:98
/usr/local/LLVM/llvm/include/llvm/ADT/ilist.h:282
/usr/local/LLVM/llvm/include/llvm/ADT/ilist.h:267
/usr/local/LLVM/llvm/lib/IR/SymbolTableListTraitsImpl.h:76
/usr/local/LLVM/llvm/lib/IR/BasicBlock.cpp:90
/usr/local/LLVM/llvm/lib/IR/SymbolTableListTraitsImpl.h:58
/usr/local/LLVM/llvm/lib/IR/ValueSymbolTable.cpp:75
/usr/local/LLVM/llvm/lib/IR/ValueSymbolTable.cpp:47
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:112
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:96
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:777
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:75
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:771
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:75
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:759
P.S。示例调用堆栈实际上是由llvmcontext类的破坏者产生的:LLVMContext::~LLVMContext()
。这是Java World的一个非常古老的帖子的另一个示例:Java Call stack - http to jdbc作为图片。
我的问题是,我们是否可以推释一下,设计的代码是否有问题,该代码将自己称为如此之大的深度。
我要去肢体说"是",但是您的问题和答案存在问题。
概念原因是否有戴上帽子的原因。您可以推荐循环是否终止;您可以证明它确实可以,也可以。您可以推论是否存在种族条件。您无法推论是否存在可能存在的东西。
没有标准,没有指标,没有权威会告诉您通话堆栈太深了。请记住,几乎可以避免任何任何呼叫堆栈:呼叫堆栈是图书馆的"分解"(如果愿意的话)的工件。可以想象用宏或C 模板替换函数调用。相同的逻辑效果,指令数量略低。也许更便宜,因为在线或更昂贵,因为重复的代码。但是至少堆栈指针没有改变!
因此,我将您的问题解释为:是一个大的调用堆栈,相对于实现的功能,理由仔细检查代码是否不必要的复杂性?对此,我说是的。
面对您描述的情况,我想知道其中一些电话是否是"经理"功能:某种概括的包装器没有做得太多。我记得几年前读了一个编组库,在那里 write (2)的呼叫堆栈是14个深的。大多数代码除了将数据调整为另一个抽象之外,什么都没有做任何事情。
无巧合:该库和您的库都是C 。C 使进行隐式函数调用变得容易,而破坏者就是一个示例。如果您将其作为C功能写作,我敢打赌,它会很长。在释放记忆之前,破坏者也很容易进行许多"清理"。在C中,您可能只打了免费(3)几次,然后使用它。
因此,这并不是呼叫堆栈深度本身这是一个问题。但是IMO您的本能是正确的:在少量功能上,大型呼叫堆栈表示一种超组织的意大利面条代码。重新查看功能当然不会受到伤害,也许正在寻找减少抽象数量的方法。
通常,是的,当我看到深层呼叫堆栈时,我会感到可疑,原因与James K. Lowden相似。
但是您的示例是规则的例外。看来您的代码正在遍历源代码的表示。源代码包含深度嵌套的结构,您的代码正在递归遍历这些结构。因此,呼叫堆栈将与代码嵌套一样深。这是完全期望和可以的,尽管我希望您有很多分配给堆栈的记忆。