为什么我的程序可以在 Ubuntu gcc 上运行,但不能在 OSX gcc 上运行?
所以我的作业,我在 Ubuntu 中运行它,它编译得很好并且运行得像它应该的那样。但是当我在 Mac OSX 中运行它时,它出现总线错误。这是为什么?
我正在使用 gcc -m32 source.c -o test 进行编译
这是 Mac OSX 版本(添加了前缀下划线):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char phrase[] = "slow but sure";
int sz;
int phrasesz;
char *arg;
char *result;
// Add any extra variables you may need here.
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: %s takes 1 string argument.\n", argv[0]);
exit(1);
}
// Allocate memory and copy argument string into arg.
sz = strlen(argv[1]) + 1;
arg = malloc(sz);
strcpy(arg, argv[1]);
// Allocate lots of memory for the result.
phrasesz = strlen(phrase) + 1;
result = malloc(sz * phrasesz);
// Now copy phrase into result, while replacing SPACE
// with SPACE+arg+SPACE.
__asm__("\n\
leal _phrase, %esi\n\
movl _result, %ebx\n\
outerLoop:\n\
cmpb $0, (%esi)\n\
je finished\n\
forLoop:\n\
cmpb $32,(%esi)\n\
je endLoop\n\
cmpb $0, (%esi)\n\
je finished\n\
mov (%esi), %eax\n\
mov %eax, (%ebx)\n\
incl %ebx\n\
incl %esi\n\
jmp forLoop\n\
endLoop:\n\
mov (%esi), %eax\n\
mov %eax, (%ebx)\n\
incl %ebx\n\
incl %esi\n\
movl _arg, %edx\n\
copyArgv1IntoResult:\n\
cmpb $0, (%edx)\n\
je finishedCopyingArgv1\n\
mov (%edx), %ecx\n\
mov %ecx, (%ebx)\n\
incl %ebx\n\
incl %edx\n\
jmp copyArgv1IntoResult\n\
finishedCopyingArgv1:\n\
movb $32, (%ebx)\n\
incl %ebx\n\
jmp outerLoop\n\
finished:\n\
movb $0, (%ebx)\n\
");
printf("%s\n", result);
return 0;
}
更新:
我在 gdb 调试器中运行了它,这是我收到的错误。
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x00001ee8 in finished ()
1: x/i $pc 0x1ee8 <finished+11>: mov (%eax),%eax
另外,我将删除 Ubuntu 版本,以便减少滚动。
So my homework, I ran it in Ubuntu, and it compiles fine and runs like the way it should. But when I run this in Mac OSX, it gets a bus error. Why is that?
I'm compiling with gcc -m32 source.c -o test
Here's the Mac OSX version (added prefixed underscores):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char phrase[] = "slow but sure";
int sz;
int phrasesz;
char *arg;
char *result;
// Add any extra variables you may need here.
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: %s takes 1 string argument.\n", argv[0]);
exit(1);
}
// Allocate memory and copy argument string into arg.
sz = strlen(argv[1]) + 1;
arg = malloc(sz);
strcpy(arg, argv[1]);
// Allocate lots of memory for the result.
phrasesz = strlen(phrase) + 1;
result = malloc(sz * phrasesz);
// Now copy phrase into result, while replacing SPACE
// with SPACE+arg+SPACE.
__asm__("\n\
leal _phrase, %esi\n\
movl _result, %ebx\n\
outerLoop:\n\
cmpb $0, (%esi)\n\
je finished\n\
forLoop:\n\
cmpb $32,(%esi)\n\
je endLoop\n\
cmpb $0, (%esi)\n\
je finished\n\
mov (%esi), %eax\n\
mov %eax, (%ebx)\n\
incl %ebx\n\
incl %esi\n\
jmp forLoop\n\
endLoop:\n\
mov (%esi), %eax\n\
mov %eax, (%ebx)\n\
incl %ebx\n\
incl %esi\n\
movl _arg, %edx\n\
copyArgv1IntoResult:\n\
cmpb $0, (%edx)\n\
je finishedCopyingArgv1\n\
mov (%edx), %ecx\n\
mov %ecx, (%ebx)\n\
incl %ebx\n\
incl %edx\n\
jmp copyArgv1IntoResult\n\
finishedCopyingArgv1:\n\
movb $32, (%ebx)\n\
incl %ebx\n\
jmp outerLoop\n\
finished:\n\
movb $0, (%ebx)\n\
");
printf("%s\n", result);
return 0;
}
Update:
I ran it in gdb debugger and this is the error I am getting.
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x00001ee8 in finished ()
1: x/i $pc 0x1ee8 <finished+11>: mov (%eax),%eax
Also, I am removing the Ubuntu version so there's less scrolling.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的一些指令,例如...
...一次从字符缓冲区复制一个以上字节。我想这是偶然的吧?您最好用 C 编写代码,然后使用 gcc -S 并与您手写的代码进行比较。即使缓冲区与字边界对齐,您也会将指针增加一个字节,因此一定要尝试未对齐的内存读取。 sigbus 基本上意味着你试图从一个地址读取一个字的内存,该地址指向一个不在对齐字开头的字节,但有些 CPU 会默默地继续战斗,而其他 CPU 则退出。我不知道你们的主机之间的硬件差异。
Some of your instructions, like...
...are copying more than a byte from the character buffer at a time. I assume that's accidental? You'd do well to write the code in C then use gcc -S and compare to your hand-written code. Even if the buffers are aligned to a word-boundary, you're incrementing the pointers by one byte, so certain to attempt an unaligned memory read. A sigbus basically means that you're trying to read a word's worth of memory from an address that points to a byte that's not at the start of an aligned word, but some CPUs silently if slowly battle on while others bail out. I've no idea of the hardware differences between your hosts.