在一个已编译的程序中(假设是C或C++,但我想这个问题可以扩展到任何带有调用堆栈的非VM语言) - 通常当你溢出堆栈时,会出现分段错误:
堆栈溢出是[a]原因,分段错误就是结果.
但这总是如此吗?堆栈溢出是否会导致其他类型的程序/操作系统行为?
我也问过非Linux,非Windows操作系统和非X86硬件.(当然,如果你没有硬件内存保护或操作系统支持(例如MS-DOS)那么就没有分段错误;我问的是你可能会遇到分段错误的情况但是还会发生其他事情).
注意:假设以外的堆栈溢出,该方案是有效的,而不是试图访问数组超出边界,取消引用无效指针等
什么是堆栈溢出错误?它可能会出现什么类型的程序/编程语言?是否不太可能在Web应用程序代码中出现?
这是我的正则表达式
((?:(?:'[^']*')|[^;])*)[;]
Run Code Online (Sandbox Code Playgroud)
它用分号标记一个字符串.例如,
Hello world; I am having a problem; using regex;
Run Code Online (Sandbox Code Playgroud)
结果是三个字符串
Hello world
I am having a problem
using regex
Run Code Online (Sandbox Code Playgroud)
但是当我使用大输入字符串时,我得到了这个错误
Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
Run Code Online (Sandbox Code Playgroud)
这是怎么造成的,我该如何解决?
这是我在堆栈上的第一个问题,所以请保持温和:D
我正在尝试创建hibernate OneToMany关系.当我尝试从我的数据库中获取一些数据时,我得到了StackOverflowError.但是当我删除OneToMany部分时,一切正常.这是我的REST服务的一部分,现在它运行在VMware vFabric Server和MySQL DB上.
获取示例:
@Inject
private EntityManager entityManager;
...
entityManager.find(League.class, 1);
...
entityManager.find(Team.class, 1);
Run Code Online (Sandbox Code Playgroud)
MySQL脚本:
CREATE TABLE league (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(20) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE team (
team_id int(11) NOT NULL AUTO_INCREMENT,
name varchar(20) COLLATE utf8_unicode_ci NOT NULL,
fk_leagueId int(11) NOT NULL,
PRIMARY KEY (team_id),
FOREIGN KEY (fk_leagueId) REFERENCES league(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Run Code Online (Sandbox Code Playgroud)
类别:
@XmlRootElement
@Entity
@Table(name = "team")
@Data …Run Code Online (Sandbox Code Playgroud) private static void Main(string[] args)
{
string str = null;
Logger.InitUserLogWithRotation(); // <--- error occur
...
}
Run Code Online (Sandbox Code Playgroud)
当我构建项目时,它没有错误.但是当我执行它时,它总是中止.
我试图调试项目,但第一行发生System.TypeInitializationException错误.
我已经尝试过谷歌搜索,但没有找到解决方案.
似乎任何变量初始化代码都是错误的,但找不到它.
请帮我.我是C#的新手.
谢谢.
※这是记录器类代码
public class Logger
{
private static int HDLOG_PRIORITY_DEBUG = 4;
private static int HDLOG_PRIORITY_ERROR = 1;
private static int HDLOG_PRIORITY_FATAL = 0;
private static int HDLOG_PRIORITY_INFO = 3;
private static int HDLOG_PRIORITY_WARNING = 2;
public static int LOG_LEVEL_DEBUG = 4;
public static int LOG_LEVEL_ERROR = 2;
public static int LOG_LEVEL_FATAL = 1;
public static int LOG_LEVEL_INFO …Run Code Online (Sandbox Code Playgroud) StackOverflowException当我运行以下代码时,我得到一个:
private void MyButton_Click(object sender, EventArgs e) {
MyButton_Click_Aux();
}
private static volatile int reportCount;
private static void MyButton_Click_Aux() {
try { /*remove because stack overflows without*/ }
finally {
var myLogData = new ArrayList();
myLogData.Add(reportCount);
myLogData.Add("method MyButtonClickAux");
Log(myLogData);
}
}
private static void Log(object logData) {
// my log code is not matter
}
Run Code Online (Sandbox Code Playgroud)
可能导致StackOverflowException什么?
阅读了Rauschmayer博士对es6中递归尾调用优化的描述之后,我一直试图重新创建他详细说明的递归因子函数的"零堆栈"执行.
使用Chrome调试器在堆栈帧之间切换,我发现尾部优化没有发生,并且正在为每次递归创建堆栈帧.
我也尝试通过在没有调试器的情况下调用函数来测试优化,而是传递100000给阶乘函数.这会引发"最大堆栈"错误,这意味着它实际上并未进行优化.
这是我的代码:
const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )
Run Code Online (Sandbox Code Playgroud)
结果:
Uncaught RangeError: Maximum call stack size exceeded
Run Code Online (Sandbox Code Playgroud) javascript stack-overflow optimization recursion ecmascript-6
观察StackOverflowError时如何检索完整的调用堆栈?
考虑这个简单的例子:
public class Overflow {
public Overflow() {
new Overflow();
}
public static void a() {
new Overflow();
}
public static void main(String[] argv) {
a();
}
}
Run Code Online (Sandbox Code Playgroud)
现在报告的错误是:
Exception in thread "main" java.lang.StackOverflowError
at Overflow.<init>(Overflow.java:11)
[last line repeated many times]
Run Code Online (Sandbox Code Playgroud)
但我无法在堆栈跟踪中看到main和a方法.我的猜测是因为溢出,堆栈中的最新条目取代了最旧的条目(?).
现在,如何在输出中获取a和main堆栈条目?
其背景是,我得到了一个的StackOverflowError(但是这不是一个无限递归,因为增加堆栈大小时,它不会发生),它是很难发现代码中的问题.我只获取了多行java.util.regex.Pattern代码而不是代码所谓的信息.应用程序太复杂,无法在每次调用Patterns时设置断点.
出于好奇,我正在尝试生成堆栈溢出.此代码根据OP生成堆栈溢出,但是当我在我的机器上运行它时,它会生成分段错误:
#include <iostream>
using namespace std;
int num = 11;
unsigned long long int number = 22;
int Divisor()
{
int result;
result = number%num;
if (result == 0 && num < 21)
{
num+1;
Divisor();
if (num == 20 && result == 0)
{
return number;
}
}
else if (result != 0)
{
number++;
Divisor();
}
}
int main ()
{
Divisor();
cout << endl << endl;
system ("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此外,根据这篇文章,一些例子也应该做同样的事情.为什么我会得到分段错误呢?
用于演示目的的简单类:
public class Main {
private static int counter = 0;
public static void main(String[] args) {
try {
f();
} catch (StackOverflowError e) {
System.out.println(counter);
}
}
private static void f() {
counter++;
f();
}
}
Run Code Online (Sandbox Code Playgroud)
我执行了5次上面的程序,结果是:
22025
22117
15234
21993
21430
Run Code Online (Sandbox Code Playgroud)
为什么结果每次都不同?
我尝试设置最大堆栈大小(例如-Xss256k).然后结果更加一致,但每次都不相等.
Java版本:
java version "1.8.0_72"
Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode)
Run Code Online (Sandbox Code Playgroud)
编辑
当JIT被禁用时(-Djava.compiler=NONE)我总是得到相同的数字(11907).
这是有道理的,因为JIT优化可能会影响堆栈帧的大小,并且JIT完成的工作肯定必须在执行之间变化.
尽管如此,我认为如果通过参考关于该主题的一些文档和/或JIT在这个特定示例中完成的工作的具体示例来确认该理论将导致框架大小改变将是有益的.
stack-overflow ×10
java ×4
c# ×2
c++ ×2
recursion ×2
stack ×2
.net ×1
c ×1
ecmascript-6 ×1
hibernate ×1
javascript ×1
one-to-many ×1
optimization ×1
regex ×1
volatile ×1
winforms ×1