C Valgrind报告无效的写入错误
这比我之前的Valgrind问题更加集中;在分析命令行选项时,我试图缩小写入和读取错误的范围:C Valgrind报告无效的写入错误,c,valgrind,C,Valgrind,这比我之前的Valgrind问题更加集中;在分析命令行选项时,我试图缩小写入和读取错误的范围: #include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <string.h>
#include <locale.h>
#include <bzlib.h>
#include <zlib.h>
#include "starch.h"
#define BUFMAXLEN 1024
int main(int argc, char **argv) {
if (parseCommandLineInputs( &argc, &argv ) != 0)
exit(EXIT_FAILURE);
return 0;
}
int parseCommandLineInputs(int *argc, char ***argv) {
pid_t pid;
struct utsname uts;
char uniqTag[BUFMAXLEN];
if ((*argc == 1) || (*argc > 4)) {
printUsage();
return -1;
}
if ((pid = getpid()) < 0) {
fprintf(stderr, "\n\t[starch] - Error: Could not obtain process ID\n\n");
return -1;
}
uname( &uts );
sprintf(uniqTag, "pid%d.%s", pid, uts.nodename);
switch (*argc) {
case 2: {
if (strcmp(*argv[1], "-") != 0) {
if (fileExists(*argv[1]) != 0) { /* standard input */
...
}
return 0;
}
int fileExists(char *fn) {
struct stat buf;
int i = stat (fn, &buf);
if (i == 0)
return 0;
return -1;
}
void printUsage() {
fprintf(stderr, "my usage statement\n\n");
}
当我使用valgrind
运行时,会出现以下错误:
$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes -v ../bin/starch
...
==2675== 1 errors in context 1 of 2:
==2675== Invalid read of size 8
==2675== at 0x3AB4262243: fwrite (in /lib64/libc-2.5.so)
==2675== Address 0x7fedffd68 is on thread 1's stack
==2675==
==2675==
==2675== 1 errors in context 2 of 2:
==2675== Invalid write of size 8
==2675== at 0x401AA6: parseCommandLineInputs (starch.c:217)
==2675== by 0x7FF0000AF: ???
==2675== by 0x401DFA: main (starch.c:46)
==2675== Address 0x7fedffd68 is on thread 1's stack
第一个错误是没有告诉我可以使用的任何东西,因为我没有在任何地方使用fwrite()
第二个错误出现在printUsage()
中的fprintf
语句上
第46行为下一行:
if (parseCommandLineInputs( &argc, &argv ) != 0)
fprintf(stderr, "my usage statement\n\n");
第217行为下一行:
if (parseCommandLineInputs( &argc, &argv ) != 0)
fprintf(stderr, "my usage statement\n\n");
我的应用程序有什么问题,可以解释为什么会出现这些错误?缺少太多内容,因此很难判断到底发生了什么。我想
pid
是pid\t
?
我看到的唯一一件事是:
sprintf(uniqTag, "pid%d.%s", pid, uts.nodename);
pid\u t
不一定是int
,因此sprintf
在解析其参数和混乱堆栈时可能走错了方向。但是,gcc
应该告诉您,如果您使用-Wall
进行编译,我想是这样的
尝试使用不同的编译器编译,例如,缺少太多内容,因此很难判断发生了什么。我想
pid
是pid\t
?
我看到的唯一一件事是:
sprintf(uniqTag, "pid%d.%s", pid, uts.nodename);
pid\u t
不一定是int
,因此sprintf
在解析其参数和混乱堆栈时可能走错了方向。但是,gcc
应该告诉您,如果您使用-Wall
进行编译,我想是这样的
尝试使用不同的编译器进行编译,例如,我会立即想到两件事:
- *argv[1]与(*argv)[1]不同,这可能是您的意思。数组下标优先于指针解引用。这将导致指针无效。正如许多有经验的程序员告诉你的那样:“不要试图记住运算符的优先级——如果有疑问,请使用括号,如果不只是使用括号的话。”
- -调试时,编译器标志中的O3是一个很大的禁忌。编译器会把你的代码弄得一团糟,使你的生活变得不可能。变量可以完全消失,函数可以在内联时神秘地消失。如果您的代码使用-O0编译、链接和运行(IIRC一些代码包含内联程序集需求-O1和一些(所有?)GCC版本),请使用它,否则最多使用-O1
- *argv[1]与(*argv)[1]不同,这可能是您的意思。数组下标优先于指针解引用。这将导致指针无效。正如许多有经验的程序员告诉你的那样:“不要试图记住运算符的优先级——如果有疑问,请使用括号,如果不只是使用括号的话。”
- -调试时,编译器标志中的O3是一个很大的禁忌。编译器会把你的代码弄得一团糟,使你的生活变得不可能。变量可以完全消失,函数可以在内联时神秘地消失。如果您的代码使用-O0编译、链接和运行(IIRC一些代码包含内联程序集需求-O1和一些(所有?)GCC版本),请使用它,否则最多使用-O1
#包括s,没有uts
的定义,uniqTag
或pid
)。为什么parseCommandLineInputs
中的行充满了尾随空间?您希望我们如何仅用一半的信息调试您的程序?uts在哪里,uniqTag?淀粉c的第46行和第217行是什么?您是否尝试过使用--db attach=yes?这不是完整的程序(否#包括s,没有定义uts
,uniqTag
,或pid
)。为什么parseCommandLineInputs
中的行充满了尾随空间?您希望我们如何仅用一半的信息调试您的程序?uts在哪里,uniqTag?淀粉c的第46行和第217行是什么?您是否尝试过使用--db attach=yes?谢谢您的帮助。我最终用strdup
语句替换了malloc/sprintf
语句。无论出于何种原因,这修复了valgrind错误消息。感谢您的帮助。我最终用strdup
语句替换了malloc/sprintf
语句。无论出于何种原因,这修复了valgrind错误消息。