how to resolve "SIGSEGV" error when using`strcpy`

Asked

Viewed 286 times

0

Hello,

I am facing an error "SIGSEGV":

strcpy(buffer_ReceiveAutomation, ls_buffer_PPouAUT); << ERROR

and

buffer is incomplete from recv, but if I change the sizeof(ls_buffer_PPouAUT) by the amount of characters works, why?

I am using C language in a Posix system, if anyone can help me I appreciate.

Statements:

char
*ls_buffer_PPouAUT,
*buffer_ReceivePinPad,
*buffer_ReceiveAutomation;

Initiations:

        //
        //  se ha memoria alocada
        //
        if(ls_buffer_PPouAUT    !=  NULL)
        {
            //
            //  Libera memoria alocada
            //
            free(ls_buffer_PPouAUT);
            ls_buffer_PPouAUT           =   NULL;
        }

        //
        //  Inicializa o buffer que recebera com pacote
        //
        ls_buffer_PPouAUT           =   malloc(5120*sizeof(char));

        if(ls_buffer_PPouAUT    ==  NULL)
        {

            //
            //  Exibe a mensagem
            //
            GEDI_LCD_DrawString(CENTER, APFONT_HEIGHT*20, APFONT_WIDTH, APFONT_HEIGHT, "Erro realocar memoria!");
            GEDI_CLOCK_Delay(1000);

            //
            //  Fecha Thread  Recive
            //
            pthread_detach(pthread_self());
            pthread_exit(NULL);
        }

        //ls_buffer_PPouAUT         = "TESTE";

        //
        //  Recebe pacote
        //
        ln_retorno_receive          =   recv
                                        (
                                            in_socket_handler,
                                            ls_buffer_PPouAUT,
                                            sizeof(ls_buffer_PPouAUT),
                                            0
                                        );
        //
        //  Validacao de erros
        //
        if(ln_retorno_receive   <   0)
        {

            //
            //  Exibe a mensagem
            //
            GEDI_LCD_DrawString(CENTER, APFONT_HEIGHT*20, APFONT_WIDTH, APFONT_HEIGHT, "Erro ao receber!");
            GEDI_CLOCK_Delay(1000);

            //
            //  Libera memoria alocada
            //
            free(ls_buffer_PPouAUT);
            ls_buffer_PPouAUT           =   NULL;

            //
            //  Para a transacao
            //
            in_controle_execucao            =   9;
            perror("recv");

            //
            //  Fecha Thread  Recive
            //
            pthread_detach(pthread_self());
            pthread_exit(NULL);
        }

        //
        //  Seta o fim do pacote
        //
        ls_buffer_PPouAUT[ln_retorno_receive]           =   '\0';

        GEDI_LCD_DrawString(5, APFONT_HEIGHT*18, APFONT_WIDTH*0.65, APFONT_HEIGHT*0.65,"P1 >%s<                              ", ls_buffer_PPouAUT);
        GEDI_CLOCK_Delay(1000);

Print above shows only the first 4 characters that should be received

//
//  Se ha memoria alocada
//
if(buffer_ReceiveAutomation !=  NULL)
{

    //
    //  Libera memoria alocada
    //
    free(buffer_ReceiveAutomation);
    buffer_ReceiveAutomation            =   NULL;
}

//
//  Inicializa o buffer que recebera com pacote
//
buffer_ReceiveAutomation            =   malloc(5120*sizeof(char));

if(buffer_ReceiveAutomation ==  NULL)
{

    //
    //  Exibe a mensagem
    //
    GEDI_LCD_DrawString(CENTER, APFONT_HEIGHT*20, APFONT_WIDTH, APFONT_HEIGHT, "AUT - Erro alocar memoria!");
    GEDI_CLOCK_Delay(1000);

    //
    //  Fecha Thread  Recive
    //
    pthread_detach(pthread_self());
    pthread_exit(NULL);
}

//
//  Seta buffer Local
//
strcpy(buffer_ReceiveAutomation,    ls_buffer_PPouAUT);

1 answer

2


Important note:

When you do:

ls_buffer_PPouAUT = "TESTE";

you immediately cause a memory leak (memory Leak). Previously you had allocated memory using malloc and assigned the allocation address to that variable, and on that line you simply "throw that address away" and put in the variable the address allocated by compiler for fixed string "TESTE". Thus, the memory allocated previously is lost and cannot be rescued until your application is terminated! To avoid this problem, use strcpy here also!

I couldn’t identify why your second call to strcpy be causing error since you are copying a smaller memory area (content "TESTE\0" in the variable ls_buffer_PPouAUT) to the larger allocated area (with any trash - if you are running in release - in the variable buffer_ReceiveAutomation). Otherwise the explanation would be obvious: the copy invaded the allocated space, because this function will copy bytes until it finds the string ending (the \0).

That is why good practice indicates not use strcpy, but yes strncpy (in which you need to inform the maximum size which must be copied).

Anyway, like I said, despite the memory leak there doesn’t seem to be anything necessarily wrong with the strcpy at that location. But as it involves access to memory, perhaps this error stems from some other previous operation where you made some wrong manipulation and the error didn’t happen immediately. Some compilers, for example, "clean" memory as soon as it is allocated when you run in debug mode, but do not do this when running in release mode for performance improvement reasons (i.e., leave it to you to take care of it!). Then certain errors are not so apparent when you debug.

For example: if its source string (ls_buffer_PPouAUT) nay had been initialized with "TESTE\0" and you were running in release mode, there would be garbage in the area allocated by malloc. The function strcpy will try to copy characters from this source until you find one \0, which can take a long time to be found (since the area was not initialized and only has trash). If it takes longer than the 5120 bytes allocated at destination, the copy will invade unallocated memory area (will exceed the maximum limit of the destination), and then the error will surely occur.

Moreover, hack memory (that is, copy data hereafter of the allocated area) may not be problematic for certain operating systems if this occurs within the application usage space (which is usually not the case for *Nix systems). And then the "error" can also take time to appear, producing false indications elsewhere.

Therefore, you should analyze your code more broadly to look for other leaks and/or intrusions. And even consider using strncpy in the other’s place. :)

  • 1

    Yes, I think that might be so, because debugging remotely because this code is being run on an external machine with a very rudimentary system, I will do a test just running to see if I pass this strcpy and, thanks, I will adopt the use of strncpy

  • It worked, I switched to strncpy, but I have another problem when it includes recv, he is keeping only the first 4 characters he would have received

  • I’m sorry, I don’t understand the other problem. What is "recv included"? When you say that "you are keeping only the first 4 characters," do you mean keeping where? Vc is sure to have received more than 4 characters (i.e., what is the size of the variable ln_retorno_receive?). Anyway, this site is not a forum. If you have another problem, open another question (and take advantage of the questions I have commented to make your question clear).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.