Home > OS >  Segmentation fault when writing to comport
Segmentation fault when writing to comport

Time:10-27

I am writing a small program to communicate with a USB to UART bridge (CP210x).

The program is fairly simple, but when ever I decrease the size of the outbound message array below (wm_size < 25) I get a segmentation fault. The code yielding the segmentation fault looks as follows:

HANDLE prog_com_port;

prog_com_port = CreateFileA("\\\\.\\COM4",
                        GENERIC_READ | GENERIC_WRITE,   //Request Read and Write Acess
                        0,                              //Block others from sharing Acess
                        NULL,                           //Disable Security features
                        OPEN_EXISTING,                  //Only open existing device
                        FILE_ATTRIBUTE_NORMAL,          //Used to set atributes and flags
                        NULL); 
                                                    //Handle to 
if(prog_com_port == INVALID_HANDLE_VALUE)
{
    printf("Opening COM port failed - INVALID_HANDLE_VALUE\n");
    CloseHandle(prog_com_port);
    return 1;
}
else
    printf("COM port was opened successfully \n");

SetupCommState(prog_com_port);
Sleep(2);
#define wm_size 25
int messageLength = 2;
char W_message[wm_size] = {0x01,0x01}; 

long unsigned int * bytes_sent;
BOOL Status;

Status = WriteFile(prog_com_port,                       // Handle to the Serial port
                &W_message,                             // Pointer to message buffer
                messageLength,                          // No of bytes to write
                bytes_sent,                             // Pointer to number of bytes written
                NULL);
if(!Status)
{
    printf("Failed to write to COM port - 0x00 \n");
    CloseHandle(prog_com_port);
    return 2;
}



CloseHandle(prog_com_port);

My logic tells me that setting wm_size = 2 is enough but apparently that is wrong. Can someone tell me why?

I played around with the size of wm_size and found experiemtally that 25 fixed the problem.

CodePudding user response:

wm_size = 2 is enough, the problem is elsewhere: bytes_sent is a pointer that points nowhere.

Your "fix" didn't fix anything. You are experiencing undefined behaviour (which includes apparently working fine).

You want this (all comments are mine):

DWORD messageLength = 2;               // use DWORD
DWORD bytes_sent;                      // use DWORD
char W_message[] = {0x01,0x01};        // you don't need wm_size

Status = WriteFile(prog_com_port,
                W_message,             // remove &, W_message decays into a pointer
                messageLength,
                &bytes_sent,           // put &, you need a pointer here
                NULL);

or even better: you don't need messageLength:

Status = WriteFile(prog_com_port,
                W_message,              // remove &
                sizeof(W_message),      // assuming W_message contains chars
                &bytes_sent,            // put &
                NULL);

// now bytes_sent contains the number of bytes sent (hopefully 2),
// providing WriteFile succeeded (Status is TRUE)

The usage of DWORD is highly recommended, so the types of the arguments passed to to WriteFile actually match the declaration (and the documentation). Also be aware that LPDWORD in all Microsoft documentation and header files is is the same thing as DWORD*.

  • Related