将字符串传递给函数存储在哪里

时间:2017-05-05 10:30:42

标签: c linux process operating-system gdb

在以下代码中:

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,我不知道它为什么要从内存中访问地址

2 个答案:

答案 0 :(得分:0)

"pidof -s gst-launch-0.10""r"字符串的内容存储在实现定义的区域中。通常将字符串文字放在&#34; text&#34;带代码的区域,或只读数据部分。

在将参数传递给函数的过程中,堆栈上的内容是这些字符串文字的两个地址,而不是它们的内容。这就是您无法在进程堆栈空间中找到字符串的原因。

有关内存中字符串文字放置的详细信息,请参阅this Q&A

答案 1 :(得分:0)

Popen是一个高级API,它将执行以下操作(在POSIX平台上:

  • 按shell shell语义解析字符串并构造“argv”数组
  • 打开新进程的stdin,stdout,stderr的管道
  • 将管道Dup2复制到相应的文件描述符
  • 执行新流程

因此,您的字符串本身不会出现在新的进程地址空间中。相反,它的组件将出现在传递的argv中。

相关问题