0
votes

I am debugging simple popen code by using valgrind.

code popen_test.c

#include<stdio.h>
#include <unistd.h>

int main(void)
{
    FILE *fp;

    fp = popen("lsblk", "r");
    if (fp == NULL) {
        return -1;
    }

    pclose(fp);

    return 0;
}

command for compile

gcc -g -O0 popen_test.c

command for run

valgrind --tool=memcheck --num-callers=30 --trace-children=yes --leak-check=full ./a.out

log

==5993== Memcheck, a memory error detector
==5993== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5993== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==5993== Command: ./a.out
==5993==
==5994== Memcheck, a memory error detector
==5994== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5994== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==5994== Command: /bin/sh -c lsblk
==5994==
==5995== Memcheck, a memory error detector
==5995== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5995== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==5995== Command: /bin/lsblk
==5995==
==5995==
==5995== Process terminating with default action of signal 13 (SIGPIPE)
==5995== at 0x4A971E4: write (write.c:26)
==5995== by 0x4A43787: _IO_file_write@@GLIBC_2.17 (fileops.c:1188)
==5995== by 0x4A42B87: new_do_write (fileops.c:456)
==5995== by 0x4A4482F: _IO_new_do_write (fileops.c:433)
==5995== by 0x4A4482F: _IO_do_write@@GLIBC_2.17 (fileops.c:430)
==5995== by 0x4A44147: _IO_file_close_it@@GLIBC_2.17 (fileops.c:136)
==5995== by 0x4A36CE7: fclose@@GLIBC_2.17 (iofclose.c:53)
==5995== by 0x10EAEB: ??? (in /bin/lsblk)
==5995== by 0x4A09CC7: __run_exit_handlers (exit.c:108)
==5995== by 0x4A09E2B: exit (exit.c:139)
==5995== by 0x49F5D27: (below main) (libc-start.c:342)
==5995==
==5995== HEAP SUMMARY:
==5995== in use at exit: 16,735 bytes in 10 blocks
==5995== total heap usage: 1,136 allocs, 1,126 frees, 2,262,873 bytes allocated
==5995==
==5995== 12,639 (12,456 direct, 183 indirect) bytes in 3 blocks are definitely lost in loss record 4 of 4
==5995== at 0x484A124: calloc (vg_replace_malloc.c:752)
==5995== by 0x114ED3: ??? (in /bin/lsblk)
==5995== by 0x118153: ??? (in /bin/lsblk)
==5995== by 0x10ED6B: ??? (in /bin/lsblk)
==5995== by 0x10DC0F: ??? (in /bin/lsblk)
==5995== by 0x49F5D23: (below main) (libc-start.c:308)
==5995==
==5995== LEAK SUMMARY:
==5995== definitely lost: 12,456 bytes in 3 blocks
==5995== indirectly lost: 183 bytes in 6 blocks
==5995== possibly lost: 0 bytes in 0 blocks
==5995== still reachable: 4,096 bytes in 1 blocks
==5995== suppressed: 0 bytes in 0 blocks
==5995== Reachable blocks (those to which a pointer was found) are not shown.
==5995== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5995==
==5995== For counts of detected and suppressed errors, rerun with: -v
==5995== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==5994==
==5994== HEAP SUMMARY:
==5994== in use at exit: 1,075 bytes in 30 blocks
==5994== total heap usage: 32 allocs, 2 frees, 1,211 bytes allocated
==5994==
==5994== LEAK SUMMARY:
==5994== definitely lost: 0 bytes in 0 blocks
==5994== indirectly lost: 0 bytes in 0 blocks
==5994== possibly lost: 0 bytes in 0 blocks
==5994== still reachable: 1,075 bytes in 30 blocks
==5994== suppressed: 0 bytes in 0 blocks
==5994== Reachable blocks (those to which a pointer was found) are not shown.
==5994== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5994==
==5994== For counts of detected and suppressed errors, rerun with: -v
==5994== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==5993==
==5993== HEAP SUMMARY:
==5993== in use at exit: 0 bytes in 0 blocks
==5993== total heap usage: 1 allocs, 1 frees, 256 bytes allocated
==5993==
==5993== All heap blocks were freed -- no leaks are possible
==5993==
==5993== For counts of detected and suppressed errors, rerun with: -v
==5993== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

I can see it leaks memory for popen.
Does my code have mistake ? or How to use valgrind is wrong ?
Would you give me any help ?

Thank you.

Postscript
I changed the code to avoid SIGPIPE.

#include<stdio.h>
#include <unistd.h>

int main(void)
{
    FILE *fp;
    char var[256] = {0};

    fp = popen("lsblk", "r");
    if (fp == NULL) {
        return -1;
    }

    while (fgets(var, sizeof(var), fp) != NULL)
    {
        ;
    }

    pclose(fp);

    return 0;
}

==7778== Memcheck, a memory error detector
==7778== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7778== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==7778== Command: ./a.out
==7778==
==7779== Memcheck, a memory error detector
==7779== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7779== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==7779== Command: /bin/sh -c lsblk
==7779==
==7780== Memcheck, a memory error detector
==7780== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7780== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==7780== Command: /bin/lsblk
==7780==
==7780==
==7780== HEAP SUMMARY:
==7780== in use at exit: 12,639 bytes in 9 blocks
==7780== total heap usage: 1,136 allocs, 1,127 frees, 2,262,873 bytes allocated
==7780==
==7780== 12,639 (12,456 direct, 183 indirect) bytes in 3 blocks are definitely lost in loss record 3 of 3
==7780== at 0x484A124: calloc (vg_replace_malloc.c:752)
==7780== by 0x114ED3: ??? (in /bin/lsblk)
==7780== by 0x118153: ??? (in /bin/lsblk)
==7780== by 0x10ED6B: ??? (in /bin/lsblk)
==7780== by 0x10DC0F: ??? (in /bin/lsblk)
==7780== by 0x49F5D23: (below main) (libc-start.c:308)
==7780==
==7780== LEAK SUMMARY:
==7780== definitely lost: 12,456 bytes in 3 blocks
==7780== indirectly lost: 183 bytes in 6 blocks
==7780== possibly lost: 0 bytes in 0 blocks
==7780== still reachable: 0 bytes in 0 blocks
==7780== suppressed: 0 bytes in 0 blocks
==7780==
==7780== For counts of detected and suppressed errors, rerun with: -v
==7780== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==7779==
==7779== HEAP SUMMARY:
==7779== in use at exit: 1,075 bytes in 30 blocks
==7779== total heap usage: 32 allocs, 2 frees, 1,211 bytes allocated
==7779==
==7779== LEAK SUMMARY:
==7779== definitely lost: 0 bytes in 0 blocks
==7779== indirectly lost: 0 bytes in 0 blocks
==7779== possibly lost: 0 bytes in 0 blocks
==7779== still reachable: 1,075 bytes in 30 blocks
==7779== suppressed: 0 bytes in 0 blocks
==7779== Reachable blocks (those to which a pointer was found) are not shown.
==7779== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==7779==
==7779== For counts of detected and suppressed errors, rerun with: -v
==7779== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==7778==
==7778== HEAP SUMMARY:
==7778== in use at exit: 0 bytes in 0 blocks
==7778== total heap usage: 2 allocs, 2 frees, 4,352 bytes allocated
==7778==
==7778== All heap blocks were freed -- no leaks are possible
==7778==
==7778== For counts of detected and suppressed errors, rerun with: -v
==7778== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

SIGPIPE does not show up but it looks memory leak occurs on a popen process.

1

1 Answers

2
votes

No, your program (in process 5993) doesn't leak.

==5993== HEAP SUMMARY:
==5993== in use at exit: 0 bytes in 0 blocks
==5993== total heap usage: 1 allocs, 1 frees, 256 bytes allocated
==5993==
==5993== All heap blocks were freed -- no leaks are possible

lsblk (in process 5995) still had memory allocated, but that's normal because the process was killed (by SIGPIPE) before the program completed.

==5995== Process terminating with default action of signal 13 (SIGPIPE)

A process receives a SIGPIPE signal when it writes to a closed pipe or socket. (lsblk's stdout, in this case.)