有那么一刻,我为自己编写了我的第一个无错误的无错误程序感到非常自豪.这是完整的源代码:
int main;
Run Code Online (Sandbox Code Playgroud)
即使没有int,它也可以完美地编译,但会发出警告(即使没有-Wall),作为一个针对无错误程序的程序员,我将它们视为错误.
我愉快地编写了这个应用程序,我立即赶紧启动它.令我惊讶的是,出现了分段错误错误......
现在认真.究竟发生了什么?
我的猜测如下:缺乏main定义.这是如此明显,但编译器允许它.好的,main可以在不同的单元中定义.但即使链接器也没有做任何事情.有什么特别的原因吗?
我正在尝试编写代码来反转字符串(我只是想在C编程和指针操作方面做得更好),但我无法弄清楚为什么我会遇到分段错误:
#include <string.h>
void reverse(char *s);
int main() {
char* s = "teststring";
reverse(s);
return 0;
}
void reverse(char *s) {
int i, j;
char temp;
for (i=0,j = (strlen(s)-1); i < j; i++, j--) {
temp = *(s+i); //line 1
*(s+i) = *(s+j); //line 2
*(s+j) = temp; //line 3
}
}
Run Code Online (Sandbox Code Playgroud)
它是第2行和第3行导致分段错误.我知道可能有更好的方法来做到这一点,但我有兴趣找出我的代码中特别导致分段错误的内容.
更新:我已根据要求包含了调用函数.
我正在试图弄清楚如何执行存储在内存中的机器代码.
我有以下代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE* f = fopen(argv[1], "rb");
fseek(f, 0, SEEK_END);
unsigned int len = ftell(f);
fseek(f, 0, SEEK_SET);
char* bin = (char*)malloc(len);
fread(bin, 1, len, f);
fclose(f);
return ((int (*)(int, char *)) bin)(argc-1, argv[1]);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在GCC中编译得很好,但是当我尝试从命令行执行程序时,如下所示:
./my_prog /bin/echo hello
Run Code Online (Sandbox Code Playgroud)
程序段错误.我已经发现问题出在最后一行,因为评论它会阻止段错误.
我不认为我做得很对,因为我仍在考虑功能指针.
这个问题是错误的演员,还是其他什么?
我正在运行命令行PHP作业,导致分段错误.这项工作已经工作了很长时间,但它会处理通过电子邮件发送的内容.显然,这封电子邮件中有些内容可以解决,但我不知道是什么.如果我把核心文件放在gdb中,那真的没有用:
$ gdb /usr/local/bin/php core.20381
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/local/bin/php...done.
[New Thread 20381]
warning: Can't read pathname for …Run Code Online (Sandbox Code Playgroud) 例如,当我们调用say,一个递归函数时,连续调用存储在堆栈中.但是,由于错误无效,因此错误是"分段错误"(如GCC所示).
它不应该是'堆栈溢出'吗?那两者之间的基本区别是什么?
顺便说一句,解释比维基百科链接更有帮助(经历过这一点,但没有特定查询的答案).
当我查看gdb中的backtrace时,我的应用程序有时会主要在malloc()和malloc_consolidate()中进行段错误.
我确认机器有足够的可用内存,甚至没有开始交换.我检查了ulimits的数据分段和最大内存大小,两者都设置为'无限'.我还在valgrind下运行了应用程序,但没有发现任何内存错误.
现在我没有想到还有什么可能导致这些段错误.有任何想法吗 ?
更新: 由于我没有找到valgrind(或ptrcheck)的任何内容,可能是因为另一个应用程序正在破坏libc的内存结构,还是每个进程都有一个单独的结构?
我一生中见过许多核心垃圾场,但这一次让我难过.
语境:
以下是崩溃的详细信息:
Program terminated with signal 11, Segmentation fault.
#0 0x00000000017bd9fd in Foo()
(gdb) x/i $pc
=> 0x17bd9fd <_Z3Foov+349>: rex.RB orb $0x8d,(%r15)
(gdb) x/6i $pc-12
0x17bd9f1 <_Z3Foov+337>: mov (%rbx),%eax
0x17bd9f3 <_Z3Foov+339>: mov %rbx,%rdi
0x17bd9f6 <_Z3Foov+342>: callq *0x70(%rax)
0x17bd9f9 <_Z3Foov+345>: cmp %eax,%r12d
0x17bd9fc <_Z3Foov+348>: mov %eax,-0x80(%rbp)
0x17bd9ff <_Z3Foov+351>: jge 0x17bd97e <_Z3Foov+222>
Run Code Online (Sandbox Code Playgroud)
您会注意到崩溃发生在指令中间0x17bd9fc,即从调用返回0x17bd9f6到虚函数之后.
当我检查虚拟表时,我发现它没有以任何方式损坏:
(gdb) x/a $rbx
0x2ab094951f80: 0x3f8c550 <_ZTI4Foo1+16>
(gdb) x/a 0x3f8c550+0x70
0x3f8c5c0 <_ZTI4Foo1+128>: 0x2d3d7b0 …Run Code Online (Sandbox Code Playgroud) 神奇的咒语
LD_PRELOAD=/lib/libSegFault.so someapp
Run Code Online (Sandbox Code Playgroud)
someapp与libSegFault.so一起运行,提供有关SIGSEGV的回溯信息,如许多 不同的 地方所述.
除了使用类似signal(7)方法来SIGABRT调用SIGSEGV处理程序之外,还有一些方法可以让libSegFault为assert(3)失败提供回溯信息吗?
我在Android WebView中有一个复杂的,交互式的HTML5 - 它基本上可以在除Galaxy S3之外的所有平台上正常工作.在Galaxy S3(Android 4.0.4)上,每5次左右,在加载完成后,/ system/lib/libwebcore.so尝试在[各地址]访问无效内存和致命信号11(SIGSEGV) ](code = 1)被抛出.
HTML5是一场微小的战斗,敌人出现,用户斜线进行.在战斗之间是正常的html页面:正常页面 - > HTML5战斗 - >正常页面 - > HTML5战斗 - >正常页面 - > HTML5战斗.HTML5没有做任何特别开箱即用的事情 - 有很多-webkit-animation调用......
.enemy {
position:absolute;
opacity:0;
-webkit-animation:enemyAnim 0.6s linear 0.2s;
}
Run Code Online (Sandbox Code Playgroud)
...引用了很多-webkit-keyframes ......
@-webkit-keyframes enemyAnim {
from {
-webkit-transform: matrix(1, 0, 0, 1, 144.25, 150.25) scale(1, 1);
opacity:1;
}
8.33% {
-webkit-transform: matrix(1, 0, 0, 1, 189.406, 102.206) scale(1.3066, 1.3066);
opacity:1;
}
16.66% {
-webkit-transform: matrix(1, 0, 0, 1, 200.424, 82.649) scale(1.414, 1.414);
opacity:1;
} …Run Code Online (Sandbox Code Playgroud) 我正在使用Java Native Interface为内部网络和网络测试工具的C库编写Java命令行界面.C代码(我没有写)是复杂的低级别,通常在位级别操作内存,并且只使用原始套接字.应用程序是C端的多线程(后台运行的pthread)以及Java端(ScheduledThreadPoolExecutors运行调用本机代码的线程).也就是说,C库应该基本稳定.事实证明,Java和JNI接口代码会导致问题.
应用程序在进入本机C函数时崩溃并出现分段错误.这仅在程序处于特定状态时才会发生(即,成功运行特定本机函数会导致下一次调用另一个特定本机函数进行段错误).此外,当应用程序崩溃时,应用程序崩溃时会出现类似的段错误quit发出命令,但同样,只有在成功运行相同的特定本机函数之后才会.
我是一个没有经验的C开发人员和经验丰富的Java开发人员 - 我习惯崩溃,给我一个特定的原因和一个特定的行号.在这种情况下,我所有的工作就是hs_err_pid*.log输出和核心转储.在这个问题的最后,我已经包含了我所能做的.
System.out.println()在Java端的本机调用之前放置了一个权限,并且printf()作为本机函数的第一行,程序崩溃fflush(stdout)后必须直接使用.该System.out呼叫跑和printf呼吁没有.这告诉我,在进入函数时发生了段错误 - 这是我以前从未见过的.jint).另外两个(JNIEnv *env, jobject j_object)是JNI构造,并且不受我的控制.return 0;.段错仍然发生.这让我相信问题不在这个功能中.env指针的值和&j_object接近另一个函数末尾的值,以确保我没有以某种方式破坏它们.我不知道我是否损坏了它们,但是在退出函数时它们都具有非零值.所有这一切都困扰着我.如果我注释掉整个函数,除了返回语句之外,为什么它仍然是段错误?如果问题出现在这个其他功能中,为什么不在那里失败?如果第一个函数弄乱内存并且第二个函数非法访问损坏的内存是一个问题,为什么不在非法访问的行上失败,而不是进入函数?
如果您看到一篇互联网文章,其中某人解释了与我类似的问题,请对其进行评论.有很多段错误的文章,似乎都没有包含这个特定的问题.对于SO问题同样如此.问题也可能是我没有足够的经验来应用这个问题的抽象解决方案.
什么可以导致Java本机函数(在C中)在这样输入时出现段错误?我可以找到哪些具体的东西来帮我压扁这个bug?我怎样才能在将来编写代码来帮助我避免这个问题呢?
为了记录,我实际上无法发布代码.如果您认为代码的描述会有所帮助,请注释,我将对其进行编辑.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00002aaaaaf6d9c3, pid=2185, tid=1086892352
#
# JRE version: 6.0_21-b06 …Run Code Online (Sandbox Code Playgroud)