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*
.