有没有人知道为什么会发生这种情况?
我在AIX 5.3中有一个C程序,我被要求在SPARC Solaris 10机器上运行它,但是当我这样做时,我注意到有一个缓冲区溢出,其中有许多鲁莽的strcat使用。我的目标不是清理代码,而是提供一个具体而有根据的答案,说明为什么在Solaris上发生这种溢出而不是AIX上的完全相同的错误编码程序。
我一直在读一下这是否可能是由于:
引起的 AIX和Solaris之间的endianess差异。
执行strcat函数(AIX从右到左复制,Solaris从左到右复制)但我无法找到任何相关文档。
您可以获得的任何亮点都非常受欢迎。
编辑:使用solaris上的noexec_user_stack标志可以避免这种情况吗?
编辑2:有没有人有关于两个操作系统进行实际字节复制的方式的任何信息?在上述选项2的情况下?
编辑3:这是代码块:
/*global*/
char bufferA[101];
/*inside function*/
bufferA[0]='\0';
strcpy(bufferA,"1");
if (atoi(something)==0) {
strcat(bufferA,pieces_of_data);
count ++ ;
}
显然它有更多,但这是使用bufferA的唯一部分,并且在缓冲区A之后有2个变量被声明为全局,并且最后一个字符串的最后一部分被附加到缓冲区A。
正如我之前所说,如果我将声明从101更改为201,则不会发生腐败。
编辑4:有没有人对solaris上的-misalign和-misalign2编译器选项有所了解?这些选择会有什么亮点吗?实际上更好的问题是:AIX powerPC和Solaris SPARC之间在对齐方面有什么区别吗?这可能是服务器故障的一个问题,但如果你知道的话请分享。答案 0 :(得分:2)
它是(坏的)运气,或许是一个略有不同的内存管理系统的人工制品,在AIX上分配的空间比在Solaris上多。
这部分取决于溢出的严重程度。如果它们是一个超出边界和的几个字节,如果AIX习惯性地分配,例如,Solaris分配16字节最小块的32字节最小块,那么在AIX上没有损坏的错误空间比Solaris操作系统。即便如此,如果你在错误的上下文中弄错了,那么AIX也应该有问题 - 你可以认为自己不是没有在AIX上观察到这个问题,就像你说的那样,它肯定会在那里发生就像它一样多在Solaris上,如果您正在编译的源代码是相同的。
进一步调查显示:
但是,如果您在AIX和Solaris之间更改了32位和64位版本,则可能仍然是您的问题的根源。
无论答案是什么,现在你都知道了,通过一组更改为两个平台修复它。你感激地对待每一个这样暴露的虫子;在任何时候,原始平台的变化都可能揭示问题 - 导致客户不满意的主要问题。
(哦,我认为SPARC和PPC都是大端机器;英特尔是小端的,与世界其他地方不同。)
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int sz ;
char *buffer;
for (sz = 1; sz < 1025; sz *= 2)
{
buffer = malloc(sz);
printf("0x%08lX\n", (unsigned long)buffer);
}
return 0;
}
答案 1 :(得分:1)
如果它发生在一个平台上,则会发生在另一个平台上。 你很幸运,在一个平台上的内存布局 导致错误显现。
如果你有一个无人看守的 strcpy / cats 的热气腾腾的土堆乱丢你的代码, 修复代码。不要责怪平台。归咎于作者。
Valgrind是你的朋友。
答案 2 :(得分:0)
我不确定这是否算作答案,但快速而肮脏的修复可能是使用malloc
搜索并替换代码中workaround_malloc
的所有实例,并将后者实现为对malloc(size+100)
的调用..: - )
答案 3 :(得分:0)
这可能是该处理器依赖的错误表现形式。数据的填充和对齐通常都由目标处理器的特性决定。额外的填充字节可能会将错误隐藏在一个目标上,而在另一个目标上则会有更少的填充字节。
它也可能与strcat传递的实际数据有所不同。例如,如果它构建的字符串的一部分由OS,处理器的名称或系统文件的路径组成。
也可能是字符串分配的大小基于标题常量或sizeof
,这对于不同的目标是不同的,因此您的实际缓冲区更小。
我可能尝试的一件事是让编译器为每个目标生成源文件的预处理版本并进行区分。它们在初始头代码中可能会有很大不同,但在代码结束时应该大致相似。查看该代码中是否存在任何可疑差异。遗憾的是sizeof
在这里不会被数字替换,但宏常量将是。
答案 4 :(得分:0)
以下是使用Solaris Studio调试器查找内存访问/使用错误的方法:
1: Download studio
http://www.oracle.com/technetwork/server-storage/solarisstudio/overview/index.html
2: Install it
Uncompress/Extract the downloaded file somewhere in your disk
Run the installer
3: Recompile your program with debugging on
$ PATH=$PATH:/opt/<studio-installation-directory>/bin
$ cc -g program.c
4: Launch your program under debugger control
$ dbx program
5: Enable run time checking
(dbx) check -all
access checking - ON
memuse checking - ON
6: Run your program
(dbx) run
7: Watch all the error messages
...