C 仅在初始执行时出现分段错误。seg故障的原因似乎发生了变化
此问题与BeagleBone Black上的PWM模块直接相关。这里有两个问题与此相关,但他们没有提供答案,而是提供了在我看来更加混乱和不必要的替代方案C 仅在初始执行时出现分段错误。seg故障的原因似乎发生了变化,c,segmentation-fault,beagleboneblack,C,Segmentation Fault,Beagleboneblack,此问题与BeagleBone Black上的PWM模块直接相关。这里有两个问题与此相关,但他们没有提供答案,而是提供了在我看来更加混乱和不必要的替代方案 int setPWMPeriod(int helpnum, char* pin, int period) { FILE *pwm; char buf[5]; char buf2[60] = "/sys/devices/ocp.3/pwm_test_"; //build file path sprintf
int setPWMPeriod(int helpnum, char* pin, int period)
{
FILE *pwm;
char buf[5];
char buf2[60] = "/sys/devices/ocp.3/pwm_test_";
//build file path
sprintf(buf,"%i",helpnum);
printf("%s\n",pin);
strcat(buf2,pin);
strcat(buf2,".");
strcat(buf2,strcat(buf,"/period"));
printf("%s\n",buf2);
pwm = fopen(buf2, "w");
if(pwm == NULL) printf("PWM Period failed to open\n");
fflush(pwm);
//fseek(pwm,0,SEEK_SET);
fprintf(pwm,"%d",period);
fflush(pwm);
fclose(pwm);
return 0;
}
以下代码是用于启动和调整PWM信号的许多功能之一。这段代码有一个警告,在初始执行时会出现分段错误。之后每次执行都没有问题。此功能在另一个程序开始时调用,以设置PWM信号。使用gdb,我将问题缩小到fseek()/fprintf()函数。最初,SIGSEGV是从fseek()收到的,但在阅读了一些内容后,我决定对其进行注释。然后,由fprintf()生成SIGSEGV
我真的不知道为什么会发生这种情况,因为还有两个其他函数具有完全相同的设置,它们在此之前执行,并且不会导致分段错误
请看一看,如果有什么突出的地方请告诉我。如有必要,我可以发布附加代码
int setPWMPeriod(int helpnum, char* pin, int period)
{
FILE *pwm;
char buf[5];
char buf2[60] = "/sys/devices/ocp.3/pwm_test_";
//build file path
sprintf(buf,"%i",helpnum);
printf("%s\n",pin);
strcat(buf2,pin);
strcat(buf2,".");
strcat(buf2,strcat(buf,"/period"));
printf("%s\n",buf2);
pwm = fopen(buf2, "w");
if(pwm == NULL) printf("PWM Period failed to open\n");
fflush(pwm);
//fseek(pwm,0,SEEK_SET);
fprintf(pwm,"%d",period);
fflush(pwm);
fclose(pwm);
return 0;
}
编辑:一些附加信息。helpnum=“15”,pin=“P8_13”您声明了一个可以容纳4个字符字符串的缓冲区(加上
\0
):
在其中打印一个int
,我们希望它的长度不超过4个字符
sprintf(buf,"%i",helpnum);
然后添加7个字符:
strcat(buf2, /* ---> */ strcat(buf,"/period") /* <--- */ );
strcat(buf2,/*-->*/strcat(buf,“/period”)/*参见以下语句-
sprintf(buf,"%i",helpnum); //if `helpnum` is a 5 digit number then UB
.....
strcat(buf2,strcat(buf,"/period"));
strcat(buf,“/period”)
这将使数组溢出buf
,因为它只有大小5
您需要相应地增加buf
的大小,如下所示-
char buf[50];
在将空终止符('\0'
)传递给字符串操作函数时,还要为其留出空间
注意-还要看看helpnum
是否不应该大于4
位,否则它会导致未定义的行为。我不认为这是问题所在,除非出于某种原因它是抢占的。helpnum始终为15。我继续操作,使缓冲区变大,但分段错误仍然发生。@Moeman69那么你可能已经溢出了buf2
,不能说,因为我们不知道pin
的长度以及你附加到其中的其他内容。我添加了一些额外的细节。helpnum一致地是两位数字(15),pin是5(第8页)。我将两个缓冲区都扩展到100,但问题仍然存在。因此我不确定这是否是缓冲区溢出问题。如果是这种情况,不是每次都会发生吗?不仅仅是在首次运行时?fseek()/fprintf()的一些相关问题分段错误暗示打开文件失败时存在地址指针问题。但是我仍然不明白为什么第二次运行时它会工作。思考?@Moeman69它导致了未定义的行为,所以每次都期望相同的行为是不可能的。我看不到任何其他问题,因为您也检查了的返回>fopen
如果不存在,它将创建一个新文件。您可能需要查看调用函数。是的,我尝试过。没有骰子。如果以前的函数使用相同的代码pwm=fopen(buf2,“w”),可能会出现问题吗;但我正在更改buf2?我确保在每个函数的末尾刷新并关闭pwm,但我真的不确定为什么会出现此问题。@Moeman69这是一个明显的错误。您的程序可能有多个错误。如果无法打开文件,则不应继续尝试访问它。发生这种情况时,您需要从函数返回。