在以下代码中:
FILE * cmd = popen(“pidof -s gst-launch-0.10”,“r”);
String“pidof -s gst-launch-0.10”存储在Process地址空间中的哪个位置。我没有在堆栈中看到它..
添加整个代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#define TRUE 1
#define FALSE 0
#define VS_STREAMER_ON 1
#define VS_STREAMER_OFF 2
#define VS_VIDSIG_ON 3
#define VS_VIDSIG_OFF 4
#define VS_VSIG_BL_OFF 5
typedef int bool;
bool bVidSignal, bVidSignalOld = FALSE;
int iVidState = VS_STREAMER_OFF;
bool IsStreamerRunning();
bool stopStreamer();
bool startStreamer();
bool ShowNoSignal()
{
printf("\nShowNoSignal()\n");
system("dd if=/home/TDS/DiskOnChip/nosig.bmp of=/dev/fb0");
return TRUE;
}
bool GetVideoSignal()
{
char buffer[10];
memset(buffer, '\0', 10);
int fd = open("/sys/bus/i2c/devices/1-000f/sysstatus", O_RDONLY, 0);
//int fd = open("/sys/bus/i2c/drivers/tc358743_mipi/1-000f/sysstatus", O_RDONLY, 0);
if (fd > 0)
{
read(fd, buffer, sizeof(buffer));
if (strlen(buffer) > 0)
{
long val = strtoul(buffer, NULL, 16);
close(fd);
if (val == 0x8F)
{
return TRUE;
}
else
{
return FALSE;
}
}
}
else
{
printf("GetVideoSignal(): can't open file\n");
}
return FALSE;
}
void CheckVideoState(void)
{
//static int iRestartCnt = 0;
static int iAppCheckTic = 60; // To Run for the first time
static int iVideoOn = FALSE;
static int iGstreamerStartCount = 0;
static int iGstreamerStartAttempt = 0;
static int iGstreamerStopCounter = 0;
bVidSignal = GetVideoSignal();
if ( (bVidSignal) && (bVidSignalOld) )
{
iVideoOn = TRUE;
printf("CheckVideoState() VideoOn=%d, MIPI_Status=%d, MIPI_Last_Status=%d\n",iVideoOn, bVidSignal, bVidSignalOld);
}
else if ( (!bVidSignal) && (!bVidSignalOld) )
{
iVideoOn = FALSE;
printf("CheckVideoState() VideoOn=%d, MIPI_Status=%d, MIPI_Last_Status=%d\n",iVideoOn, bVidSignal, bVidSignalOld);
}
else
{
printf("CheckVideoState() VideoOn=%d, MIPI_Status=%d, MIPI_Last_Status=%d\n",iVideoOn, bVidSignal, bVidSignalOld);
}
bVidSignalOld = bVidSignal;
switch (iVidState)
{
case VS_STREAMER_OFF:
if ( iVideoOn )
{
iGstreamerStartCount = 0;
iGstreamerStartAttempt = 0;
printf("CheckVideoState():VS_STREAMER_OFF: Signal ON\n");
iVidState = VS_VIDSIG_ON;
}
else
{
iAppCheckTic++;
if ( iAppCheckTic >= 60 )
{
iAppCheckTic = 0;
iGstreamerStartCount = 0;
iGstreamerStartAttempt = 0;
if ( IsStreamerRunning() )
{
printf("CheckVideoState():VS_STREAMER_OFF: Killing Gstreamer\n");
stopStreamer();
sleep(1);
ShowNoSignal();
}
}
}
break;
case VS_VIDSIG_ON:
if ( iGstreamerStartAttempt > 5 )
{
printf("CheckVideoState():calling Reboot after 5 Gstreamer Restarts!\n");
//SystemExit(SS_REBOOT);
system("reboot");
}
if ( iGstreamerStartCount == 0 )
{
if ( IsStreamerRunning() )
{
iGstreamerStopCounter = 0;
iVidState = VS_VIDSIG_OFF;
printf("CheckVideoState():VS_VIDSIG_ON: GStreamer Running Already Switch to VS_VIDSIG_OFF\n");
}
else
{
startStreamer();
printf("CheckVideoState():VS_VIDSIG_ON: Starting GStreamer\n");
iGstreamerStartCount++;
iGstreamerStartAttempt++;
}
}
if ( iGstreamerStartCount >= 10 )
{
if ( IsStreamerRunning() )
{
iVidState = VS_STREAMER_ON;
printf("CheckVideoState(): VS_VIDSIG_ON: GStreamer Running After %d Seconds, Switching to VS_STREAMER_ON\n", iGstreamerStartCount);
}
else
{
iGstreamerStartCount = 0;
printf("CheckVideoState(): VS_VIDSIG_ON: GStreamer Not Running After 5 Seconds, Clearing iGstreamerStartCount\n");
}
break;
}
iGstreamerStartCount++;
break;
case VS_STREAMER_ON:
if ( iVideoOn )
{
if ( !IsStreamerRunning() )
{
iGstreamerStartCount = 0;
iGstreamerStartAttempt = 0;
printf("CheckVideoState():VS_STREAMER_ON: Gstreamer Not running even after video signal available\n");
}
}
else
{
iVidState = VS_VIDSIG_OFF;
printf("CheckVideoState():VS_STREAMER_ON: Lost Video Signal\n");
iGstreamerStopCounter = 0;
}
break;
case VS_VIDSIG_OFF:
if ( IsStreamerRunning() )
{
stopStreamer();
printf("CheckVideoState():VS_VIDSIG_OFF: Killing GStreamer\n");
}
else
{
if ( iGstreamerStopCounter >= 3 )
{
iVidState = VS_STREAMER_OFF;
printf("CheckVideoState():VS_VIDSIG_OFF: Switching to VS_STREAMER_OFF after 3 seconds\n");
break;
}
}
iGstreamerStopCounter++;
break;
}
}
pid_t GetStreamerPID()
{
pid_t pid = 0;
char line[100];
memset(line, '\0', 100);
FILE *cmd = popen("pidof -s gst-launch-0.10", "r");
if ( cmd == NULL )
{
printf("Cmd Null\n");
}
fgets(line, 100, cmd);
if (strlen(line) > 0)
{
pid = strtoul(line, NULL, 10);
}
pclose(cmd);
return pid;
}
bool IsStreamerRunning()
{
pid_t pid = GetStreamerPID();
if (pid > 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
void MainLoop()
{
while(1)
{
sleep(1);
CheckVideoState();
}
}
bool startStreamer()
{
char command[256];
pid_t pid = GetStreamerPID();
if (pid > 0)
{
}
else
{
sprintf(command, "gst-launch imxv4l2src ! imxv4l2sink &");
printf("StartStreamer: command=[%s]\n", command);
system(command);
}
return TRUE;
}
bool stopStreamer()
{
char command[256];
pid_t pid = GetStreamerPID();
if (pid > 0)
{
sprintf(command, "kill %d", pid);
printf("StopStreamer: command=[%s]\n", command);
system(command);
}
else
{
}
return TRUE;
}
int main()
{
MainLoop();
return 0;
}
代码正在崩溃,分段错误发生在CheckVideoState()的IsStreamerRunning()函数中。案例VS_VIDSIG_ON ...注意。这是随机发生的。通过gdb调试,回溯在popen停止,它正在访问不允许访问的内存。因此分割错误。任何人都可以帮助我..
添加gdb回溯:
Breakpoint 1, 0x76ea6ffc in popen@@GLIBC_2.4 () from /lib/libc.so.6
#0 0x76ea6ffc in popen@@GLIBC_2.4 () from /lib/libc.so.6
#1 0x00010d14 in GetStreamerPID () at getPid.c:243
#2 0x00010d98 in IsStreamerRunning () at getPid.c:263
#3 0x00010aac in CheckVideoState () at getPid.c:157
#4 0x00010dd4 in MainLoop () at getPid.c:284
#5 0x00010efc in main () at getPid.c:358
Program received signal SIGSEGV, Segmentation fault.
0x80808080 in ?? ()
(gdb) bt
#0 0x80808080 in ?? ()
#1 0x76ee1b70 in fork () from /lib/libc.so.6
#2 0x76ea6d80 in _IO_proc_open@@GLIBC_2.4 () from /lib/libc.so.6
#3 0x76ea704c in popen@@GLIBC_2.4 () from /lib/libc.so.6
#4 0x00010d14 in GetStreamerPID () at getPid.c:243
#5 0x00010d98 in IsStreamerRunning () at getPid.c:263
#6 0x00010aac in CheckVideoState () at getPid.c:157
#7 0x00010dd4 in MainLoop () at getPid.c:284
#8 0x00010efc in main () at getPid.c:358
我正在调试过去一周,使用valgrind,gdb,我不知道它为什么要从内存中访问地址
答案 0 :(得分:0)
"pidof -s gst-launch-0.10"
和"r"
字符串的内容存储在实现定义的区域中。通常将字符串文字放在&#34; text&#34;带代码的区域,或只读数据部分。
在将参数传递给函数的过程中,堆栈上的内容是这些字符串文字的两个地址,而不是它们的内容。这就是您无法在进程堆栈空间中找到字符串的原因。
有关内存中字符串文字放置的详细信息,请参阅this Q&A。
答案 1 :(得分:0)
Popen是一个高级API,它将执行以下操作(在POSIX平台上:
因此,您的字符串本身不会出现在新的进程地址空间中。相反,它的组件将出现在传递的argv中。