gdb and multi-threaded applications.
jjs
Jerry.Sexton at insignia.com
Wed Mar 15 21:18:50 EST 2000
>Note to Jerry: I'd still like a small example, preferably one that
>we could eventually put into the testsuite.
>
>Kevin
>
Kevin,
OK, here is an example.
gdb_thread.c
=================================================================
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
char *signame[] =
{
"0",
"SIGHUP",
"SIGINT",
"SIGQUIT",
"SIGILL",
"SIGTRAP",
"SIGABRT",
"SIGBUS",
"SIGFPE",
"SIGKILL",
"SIGUSR1",
"SIGSEGV",
"SIGUSR2",
"SIGPIPE",
"SIGALRM",
"SIGTERM",
"SIGSTKFLT",
"SIGCHLD",
"SIGCONT",
"SIGSTOP",
"SIGTSTP",
"SIGTTIN",
"SIGTTOU",
"SIGURG",
"SIGXCPU",
"SIGXFSZ",
"SIGVTALRM",
"SIGPROF",
"SIGWINCH",
"SIGIO",
"SIGPWR",
"SIGUNUSED",
"SIG32",
"SIG33",
"SIG34",
"SIG35",
"SIG36",
"SIG37",
"SIG38",
"SIG39",
"SIG40",
"SIG41",
"SIG42",
"SIG43",
"SIG44",
"SIG45",
"SIG46",
"SIG47",
"SIG48",
"SIG49",
"SIG50",
"SIG51",
"SIG52",
"SIG53",
"SIG54",
"SIG55",
"SIG56",
"SIG57",
"SIG58",
"SIG59",
"SIG60",
"SIG61",
"SIG62",
"SIG63"
};
#define NSIGS (sizeof(signame) / sizeof(signame[0]))
void
attrInit(pthread_attr_t *attrPtr)
{
struct sched_param schedParam;
schedParam.sched_priority = 0;
pthread_attr_init(attrPtr);
pthread_attr_setdetachstate(attrPtr, PTHREAD_CREATE_DETACHED);
pthread_attr_setschedpolicy(attrPtr, SCHED_OTHER);
pthread_attr_setschedparam(attrPtr, &schedParam);
pthread_attr_setinheritsched(attrPtr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setscope(attrPtr, PTHREAD_SCOPE_PROCESS);
pthread_setschedparam(pthread_self(), SCHED_OTHER, &schedParam);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}
void *
threadStartPoint(void *arg)
{
int retVal;
printf("Thread started successfully.\n");
return NULL;
}
main(int argc, char *argv[])
{
pthread_t newThread;
sigset_t sigmask;
sigset_t fullSigMask;
pthread_attr_t threadAttr;
int err;
int signal;
if (argc == 2)
{
signal = atoi(argv[1]);
}
else
{
fprintf(stderr, "usage: thread signal\n");
exit(-1);
}
attrInit(&threadAttr);
sigemptyset(&sigmask);
sigaddset(&sigmask, signal);
sigfillset(&fullSigMask);
if (pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == 0)
{
printf("Blocked signal %s before creating thread.\n", signame[signal]);
}
else
{
printf("Failed to block signal %s before creating thread.\n",
signame[signal]);
exit(-1);
}
err = pthread_create(&newThread, &threadAttr,
(void *(*)(void *)) threadStartPoint,
(void *) NULL);
switch(err)
{
case 0:
printf("pthread_create succeeded\n");
break;
case EAGAIN:
printf("pthread_create failed: System resources not available\n");
break;
case EINVAL:
printf("pthread_create failed: Invalid thread attributes\n");
break;
default:
printf("pthread_create failed: Unknown error - %d\n", err);
break;
}
exit(0);
}
Makefile
====================================================================
CFLAGS=-g
CC=gcc
gdb_thread: gdb_thread.o
gcc -g -o $@ gdb_thread.o -lpthread
===========================================================================
Running this program under gdb, I get the following output:
(gdb) r 1
Starting program: /tmp_mnt/home/wolf/jjs/src/thread/gdb_thread 1
Blocked signal SIGHUP before creating thread.
[New Thread 12358 (manager thread)]
[New Thread 12352 (initial thread)]
[New Thread 12359]
pthread_create succeeded
Program exited normally.
(gdb) r 2
Starting program: /tmp_mnt/home/wolf/jjs/src/thread/gdb_thread 2
Blocked signal SIGINT before creating thread.
[New Thread 12366 (manager thread)]
[New Thread 12360 (initial thread)]
[New Thread 12367]
pthread_create succeeded
Program exited normally.
(gdb)
Note that the "Thread started successfully." message from threadStartPoint
is not printed out. I think this is just because we fall off the end of the
program before we get a chance to ececute the printf. This pattern is
repeated for all signal numbers except 34, which gives the following output:
(gdb) r 34
Starting program: /tmp_mnt/home/wolf/jjs/src/thread/gdb_thread 34
Blocked signal SIG34 before creating thread.
and then gdb hangs and I have to kill gdb_thread externally to continue.
Note that I tried blocking each signal in turn in a loop first of all and
the program sailed past signal 34 without a problem. Experimenting a little,
it turns out that after pthread_create succeeds once, it will subsequently
succeed under gdb even if signal 34 is blocked.
I have tried running our proprietory application under gdb with all signals
except signal 34 blocked when pthread_create is called and it works fine. I
will make sure that all the signals Michael suggests are unblocked in our
application and hopefully every thing will work OK.
Thanks for your help, guys.
Cheers, Jerry.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list