服务器上出现分段错误,但本地计算机上没有分段错误
如标题所述,该程序可以在我的本地计算机(ubuntu 9.10)上运行,但不能在服务器(linux)上运行。这是godaddy的网格托管托管包。
请帮助..
这是代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
long offset;
FILE *io;
unsigned char found;
unsigned long loc;
if (argc != 2)
{
printf("syntax: find 0000000\n");
return 255;
}
offset = atol(argv[1]) * (sizeof(unsigned char)+sizeof(unsigned long));
io = fopen("index.dat","rb");
fseek(io,offset,SEEK_SET);
fread(&found,sizeof(unsigned char),1,io);
fread(&loc,sizeof(unsigned long),1,io);
if (found == 1)
printf("%d\n",loc);
else
printf("-1\n");
fclose(io);
return 0;
}
编辑:这不是我的程序。 我希望我了解足够的 C 语言来修复它,但我已经到了最后期限。该程序的目的是查找 PI 序列中第一次出现的 7 位数字,index.dat 包含一个巨大的数组数字 =>位置。
http://jclement.ca/fun/pi/search.cgi
编辑2:我已经使用更新的代码来测试空指针,仍然得到相同的结果。 该程序在我的本地计算机上运行良好,此错误仅发生在服务器上。
As stated in the title, the program is working on my local machine (ubuntu 9.10) but not on the server (linux). It's a grid hosting hosting package of godaddy.
Please help..
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
long offset;
FILE *io;
unsigned char found;
unsigned long loc;
if (argc != 2)
{
printf("syntax: find 0000000\n");
return 255;
}
offset = atol(argv[1]) * (sizeof(unsigned char)+sizeof(unsigned long));
io = fopen("index.dat","rb");
fseek(io,offset,SEEK_SET);
fread(&found,sizeof(unsigned char),1,io);
fread(&loc,sizeof(unsigned long),1,io);
if (found == 1)
printf("%d\n",loc);
else
printf("-1\n");
fclose(io);
return 0;
}
EDIT: It's not my program.
I wish I knew enough C in order to fix it, but I'm on a deadline. This program is meant to find the first occurrence of a 7 digit number in the PI sequence, index.dat contains an huge array number => position.
http://jclement.ca/fun/pi/search.cgi
EDIT 2: I've used the updated code with the test for null pointer, still getting the same results.
The program is working fine on my local machine, this error only happens on the server.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
最有可能的情况是 fopen 失败 - 您没有检查它的返回值来查看是否确实获得了有效的指针。 (当您尝试在下一行中使用该 NULL 指针时,您会遇到段错误。)
The most likely thing is that the fopen is failing - you're not checking its return value to see if you actually got a valid pointer. (You get a segfault when you try to use that NULL pointer in the next line.)
也许
unsigned long
的大小在机器上不一样。以下程序在您的机器上打印什么?
使用
gcc -std=c99 file.c
编译。如果打印的大小确实不同,则需要将unsigned long
替换为uint32_t
,并在以下位置添加#include
程序的开头:上面假设“正确工作”的程序有 4 字节
unsigned long
。如果不是,您需要将程序中的4
替换为正确计算机上unsigned long
的大小。如果这是差异的原因,那么您现在知道了读写二进制数据的问题之一:您必须非常小心大小、字节顺序等。
Maybe the sizes of
unsigned long
are not the same on the machines.What does the following program print on your machines?
Compile with
gcc -std=c99 file.c
. If the sizes printed are indeed different, then you need to replaceunsigned long
byuint32_t
, and add#include <inttypes.h>
at the beginning of your program:The above assumes that the "correctly working" program has 4 byte
unsigned long
. If not, you will need to replace the4
in the program with whatever the size ofunsigned long
on the correct computer is.If this is the reason of the difference, then you now know one of the problems with reading and writing binary data: you have to be very careful about sizes, endianness, etc.
我刚刚在 godaddy 遇到了这个问题,发现 FTP 客户端以 ASCII 格式上传,而不是二进制格式。我在上传之前将扩展名更改为
.bin
,现在可以正常使用了。I just ran into this problem with godaddy and found that the FTP client was uploading in ASCII and not Binary. I changed the extension to
.bin
before uploading and it works normally now.我最初的猜测是文件无法打开,因此 io 为 NULL。
但韦德是对的:您应该首先在程序中添加一些错误处理 - 至少这会让您(和我们)更好地了解出了什么问题。
My initial guess is that the file failed to open, and thus io is NULL.
But Wade is right: you should add some error handling to your program first - at minimum that will give you (and us) a better idea of what is going wrong.
我的猜测是,服务器上的
sizeof(long)
是 8(因为它是 64 位系统),而本地计算机上的 sizeof(long) 是 4(假设是 32 位计算机)。因此,计算出的文件偏移量将错误 2 倍。如果您需要转到文件中的特定偏移量,则应该使用固定大小类型 - 即uint32_t
等。My guess would be that
sizeof(long)
on the server is 8 (due to it being a 64-bit system), vs. 4 on your local machine (assuming a 32-bit machine). Thus your calculated offset into the file would be wrong by a factor of 2. If you need to go to a specific offset in the file, you should be using fixed-size types - i.e.uint32_t
and the like.首先,您没有向我们提供有关错误发生位置的上下文。
其次,在人们花费时间之前,您需要添加错误检查。
First, you've given us no context on where the error occurs.
Second, before people spend time on it you need to add error checking.
也许“index.dat”不在您的服务器上,但在您的计算机上。因为你用“rb”打开它,并且在 fopen 之后没有检查 io,所以很可能做到这一点。
Maybe "index.dat" isn't on your server but is on your machine. Since you're opening it with "rb" and not checking io after the fopen that could very well do it.
可以在服务器上运行gdb吗?如果是这样,请在启用调试的情况下构建(gcc 的 -g 选项)并在 gdb 中运行它。这会告诉你程序哪里失败了。方法如下(将 <> 中的内容替换为相关信息):
gdb 将捕获段错误并显示崩溃的行。
Can you run gdb on the server? If so, build with debugging enabled (-g option to gcc) and run it in gdb. That will tell you where the program is failing. Here's how (replace the stuff in <> with the relevant info):
gdb will catch the segfault and show the line where it crashed.
我认为您正在阅读超出文件限制的内容。我添加了一部分来检查文件大小并确保您在文件限制内阅读。
I think you are reading outside the file limits. I added a portion to check the file size and ensure you are reading within the file limits.
将代码的中间部分更改为:
并查看运行程序时打印哪些行。这应该会提示您问题到底出在哪里。
编辑:当我说函数调用“有效”时,我的意思是“没有导致段错误”。理想情况下,您需要检查对
fseek
和fread
的每次调用,以确保它们没有遇到任何错误,但您提到您已经到了最后期限,所以这只是一些错误fast-n-dirty 错误跟踪来尝试追踪段错误。Change the middle section of your code to:
and see which lines get printed when you run the program. That should give you a hint as to where exactly the problem is.
Edit: When I say a function call "worked", I mean "didn't cause a segfault". Ideally you would want to check each call to
fseek
andfread
to make sure they didn't encounter any errors, but you mentioned you were on a deadline so this is just some quick-n-dirty error tracing to try and track down the segfault.也许您应该尝试为找到的变量和定位变量分配一些内存?
Maybe you should try and allocate some memory for found and loc variables ?