0

I want to get the output of the u3-tool (http://u3-tool.sourceforge.net/) into a variable. The result without redirect the streams is:

$ echo "pass" | sudo -S sh -c "u3-tool -i /dev/sdc"
Total device size:   1.88 GB (2022703104 bytes)
Segmentation fault

But If I redirect the pipe to a file: echo "pass" | sudo -S sh -c "u3-tool -i /dev/sdc > /tmp/u3info 2>&1", then I get only the second line Segmentation fault!

Does anyone have an idea? Where is "Total device size: 1.88 GB (2022703104 bytes)" from the stdout?

What is Segmentation fail of the language C? How I can solve it?

King regards and Merry Christmas!

In Using is Linux Mint 17.3

2 Answers2

0

The Segmentation fault message gets printed by your shell, not by your program, when this signal is generated, and not caught, by some program which tried to access memory outside what is allocated to it.

Now, as to why you're only getting the segfault in your output, I think there are two things happening here:

  • when you invoke a shell command using sh -c, you're actually invoking the command in a new shell. The seg fault message is coming from that new shell, not the one you're working in, and when you combine stdout and stderr with 2>&1 then you're also getting the stderr for the new shell. Which contains the segfault message. If you just run the command directly in the shell you're already using (i.e. echo "pass" | sudo -S u3-tool -i /dev/sdc > /tmp/u3info 2>&1), then the redirection should work like you expect.
  • It's very possible that the seg fault is happening before the output line is fully buffered and flushed to the file, see this stackoverflow question. To answer why the output line appears in your terminal window, but not when redirected to a file, I must honestly say that I don't know why that happens, but I can verify the same behaviour on my machine with a simple program:

    #include <stdio.h>                                                              
    
    void main (void)                                                                
    {                                                                               
        char *p;           /* uninitialised pointer */                              
        printf("hello\n"); /* print a line */                                       
        p[7] = 'a';        /* seg fault! */                                         
    } 
    

    And here is what happens when I compile and test it:

    enyquist$ gcc segfault.c -o segfault
    enyquist$ ./segfault
    hello
    Segmentation fault
    enyquist$ ./segfault > file
    Segmentation fault
    enyquist$ cat file
    enyquist$ 
    

    TO illustrate the problem, we can actually fix this code, to ensure that the full message is flushed and printed before doing anything else, like so:

    #include <stdio.h>                                                              
    
    void main (void)                                                                
    {                                                                               
        char *p;           /* uninitialised pointer */                              
        printf("hello\n"); /* print a line */
        fflush(stdout);    /* flush stdout stream */                                       
        p[7] = 'a';        /* seg fault! */                                         
    }
    

    And the output....

    enyquist$ gcc segfault.c -o segfault
    enyquist$ ./segfault
    hello
    Segmentation fault
    enyquist$ ./segfault > file
    Segmentation fault
    enyquist$ cat file
    hello
    enyquist$
    

So, to summarise, if you modify your shell commands like I suggested then I think the redirection will behave like you expect, but nothing else is behaving like you expect because you're getting a seg fault somewhere, so you need to find out what's causing that!

Community
  • 1
  • 1
Erik Nyquist
  • 1,267
  • 2
  • 12
  • 26
  • Why this won't work like you expect (har har)? Please visit: http://askubuntu.com/a/470387 I don't want the `Segmentation fault` in the log, but my redirection only catch this message without the other output like Total device size! – user4742258 Dec 22 '15 at 07:04
  • My mistake, I ignored the `-S` to sudo. You're right, that will work like you expect, I'll take that out of the answer. – Erik Nyquist Dec 22 '15 at 14:16
  • At the moment I don't get the `Segmentation fault` message, but with the command `echo "pass" | sudo -S u3-tool -i /dev/sdc > /tmp/u3info 2>&1` I don't get the stdout in the file. The file is currently empty like before. – user4742258 Dec 23 '15 at 07:09
  • But the `fflush(stdout); /* flush stdout stream */` in the main.c fix the problem! Thank you and merry Christmas!# – user4742258 Dec 23 '15 at 07:15
0

Segmentation fault is an error in which the program tried to access memory it wasn't cleared to access. It will happen when the program goes out of bound of an array or memory space it was allocated or when it tries to access elements that were initialized out of its allocated memory.

You only get the second line after a redirection because it is printed on stderr which is the error output on linux.

As for the error, if you are sure the arguments for the program are correct, the only thing you can do if you do not have access to the source code is to issue a ticket to the devs.

loginn
  • 94
  • 1
  • 8
  • But with command `2>&1` I should get pipe stderr and stdout to the log. I have already check the source code from here: http://archive.ubuntu.com/ubuntu/pool/universe/u/u3-tool/u3-tool_0.3-1.1.dsc But I didn't found an error: `printf("Total device size: "); print_human_size(1ll * U3_SECTOR_SIZE * device_properties.device_size); printf(" (%llu bytes)\n", 1ll * U3_SECTOR_SIZE * device_properties.device_size);` – user4742258 Dec 22 '15 at 07:08
  • Can you launch the program with valgrind and put the logs there ? – loginn Dec 22 '15 at 14:40
  • Because valgrind is library of tools I don't know what is to do. – user4742258 Dec 23 '15 at 07:05
  • just do valgrind ./yourprogram your args – loginn Dec 24 '15 at 11:19