所以我遇到一个问题,即某段代码给了我这个错误*** BUFFER OVERFLOW DETECTED ***
。一旦我打开某些编译器优化选项(这不是我的程序,所以我必须使用这些),这才开始发生。我把它缩小到了哪个选项。我还找到了一种方法来阻止缓冲区溢出,但是,我在程序的另一部分中有非常相似的代码,当我离开它时,不会给我同样的错误。这让我非常困惑,对我的修复非常不自信,所以一些指导将不胜感激。
以下是makefile
CXXFLAGS+=-Os -O2 -fomit-frame-pointer
CXXFLAGS+=-fno-aggressive-loop-optimizations
我已将其缩小到导致错误的-O2
标志。
只有在指定了realpath()
标志时,这个函数才会在-O2
上的缓冲区溢出失败
static std::string getRealTargetPath (std::string baseTarget)
{
char nextTargetLink[MAXPATHLEN];
memset (nextTargetLink, 0, MAXPATHLEN);
if (realpath (baseTarget.c_str(), nextTargetLink) == NULL)
return "";
else
//etc...
}
如果我将MAXPATHLEN
(大小1024)更改为PATH_MAX
(大小为4096),则上述函数将按预期运行。好,可以。但是,在使用相同 std::string baseTarget
之后,以下代码片段执行~20行。
char realLinkPath[MAXPATHLEN];
memset (realLinkPath, 0, MAXPATHLEN);
do
{
if (realpath (linkPath.c_str(), realLinkPath) != NULL)
if (strcmp(linkPath.c_str(), realLinkPath) != 0)
return true;
size_t eraseFrom = linkPath.rfind('/');
if (std::string::npos != eraseFrom)
linkPath.erase(eraseFrom);
} while ( !linkPath.empty() );
总之,即使这两个realpath
函数使用相同的const char* path
变量,如果缓冲区长度不是PATH_MAX
而第二个不是-O2
,那么第一个将失败,这一切都是仅在为编译指定C
标志时才会发生。
任何帮助都将不胜感激,谢谢。
编辑:正如用户指出的那样,我也将其标记为C
,因为该程序非常陈旧,核心是用C++
编写的,我将它保留为C尽可能不使用 许多 Person person = new Person("Bob",new LocalDate(1900,02,22));
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
String json = mapper.writer().writeValueAsString(person);
Person returnPojo = mapper.readValue(json, Person.class);
System.out.print(returnPojo);
功能
答案 0 :(得分:5)
嗯,第二部分有不同的输入,所以碰巧偶然。 realpath()
是一个非常破碎的函数,即使是manpage个状态(参见 BUGS )。
你能做的最好的事情就是重新编写代码,以便用null
指针作为第二个参数来调用realpath,并注意你返回的分配缓冲区是free()
d
答案 1 :(得分:2)
realpath
的手册页指定resolved_path
的长度必须至少为PATH_MAX。如果realpath
的结果是长度超过1024字节的字符串,并且您的缓冲区不够大,则调用undefined behavior。这意味着崩溃可能(如第一种情况)或可能不会(如第二种情况)发生。