I'm currently working on an embedded application (running on linux 4.14) that implements two threads (main and a communication thread) using POSIX threads.
The communication thread creates a POSIX queue that handles command requests from the main thread (by calling mq_send()). It also can handle incoming data from a serial line that raises an SIGIO signal.
Here is a sample code
Main thread:
pthread_t com_thread;
mqd_t cmd_queue;
void main (void)
{
struct mq_attr attr;
init_serial(); // Does serial line init and set a sigaction() with SIGIO that store serial data
// Create queue
attr.mq_flags = 0;
attr.mq_maxmsg = 100;
attr.mq_msgsize = sizeof(struct Dummy);
attr.mq_curmsgs = 0;
cmd_queue = mq_open(QUEUE_NAME, // Queue name
O_RDWR | O_CREAT, // Flags
S_IRWXU|S_IRWXG|S_IRWXO, // Mode
&attr); // Attributes
// Create thread
pthread_create(&com_thread, NULL, com_fw_handler, NULL);
while(1)
{
// Do some stuff ...
// Send command request
mq_send(cmd_queue, (const char*)cmd_request, sizeof(struct Dummy), 0);
}
}
Com Thread :
static void * com_fw_handler (void * ptr)
{
struct Dummy request_from_queue;
sigset_t sig_set;
int ret = 0;
// Allow SIGIO signal
sigemptyset(&sig_set);
sigaddset(&sig_set, SIGIO);
sigprocmask(SIG_UNBLOCK, &sig_set, NULL);
while(1)
{
// Wait for a command request or SIGIO
do
{
ret = mq_receive(cmd_queue, (char*)request_from_queue, sizeof(request_from_queue), NULL);
printf("mq_received() returned %d\n", ret);
if(ret > 0)
{
// Handle command request
}
}while(ret > 0);
// If mq_receive() exited because SIGIO has been raised
if((ret < 0) && (errno == EINTR))
{
// Handle incoming data from serial
}
}
}
When I try to debug my application using GDB, everything works fine, mq_received() is exited each time the system receives data from the serial line. Here is the console output sample :
mq_received() returned 64
mq_received() returned -1
mq_received() returned 64
mq_received() returned -1
......
64 is the size of the Dummy structure, -1 is the returned value when SIGIO has been raised.
If the application is started directly on the system, SIGIO is raised (I can see a debug print on the console) but it seems mq_receive() never exit. The console outputs only:
mq_received() returned 64
mq_received() returned 64
.......
GDB session starts with following "options" :
handle all nostop pass noprint
I can't determine if the behaviour I observe is due to GDB signal handling or a race/timing problem or just a developper issue !
Anything wrong in sample code I provided ?
Thanks !