1.5.18: segmentation fault on combination of pthread_kill() and sigsuspend()
Bart Van Assche
bart.vanassche@gmail.com
Mon Nov 21 02:14:00 GMT 2005
Hello,
I wrote a small program in order to get an idea of context switch
times of the Linux kernel. The program runs fine on Linux. Valgrind
2.2.0 does report the program to be clean. Just out of curiosity, I
tried to compile and run the same program with Cygwin. However, on
cygwin it segfaults. Did I do anything wrong, or is this a cygwin bug
?
$ ./ctxtsw.exe
Iterations: 5
Segmentation fault (core dumped)
$ cat ctxtsw.exe.stackdump
Exception: STATUS_ACCESS_VIOLATION at eip=00000001
eax=00000000 ebx=00446048 ecx=00000004 edx=00000000 esi=00000001 edi=18ACEF78
ebp=18ACEF88 esp=18ACEF70
program=C:\cygwin\home\B\test\ctxtsw\ctxtsw.exe, pid 2044, thread
unknown (0x884)
cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
Stack trace:
Frame Function Args
18ACEF88 00000001 (00000000, FFFFFFFF, 18ACEFC8, 61003B7D)
18ACEFC8 6109D17E (004D07B0, 18ACF000, 6109D110, 00000000)
18ACEFF8 61003E94 (00000000, 00000000, 00000000, 00000000)
18ACFF98 61003EDA (00000000, 00000000, 00000000, 00000000)
End of stack trace
$
Cygwin DLL version info:
DLL version: 1.5.18
DLL epoch: 19
DLL bad signal mask: 19005
DLL old termios: 5
DLL malloc env: 28
API major: 0
API minor: 132
Shared data: 4
DLL identifier: cygwin1
Mount registry: 2
Cygnus registry name: Cygnus Solutions
Cygwin registry name: Cygwin
Program options name: Program Options
Cygwin mount registry name: mounts v2
Cygdrive flags: cygdrive flags
Cygdrive prefix: cygdrive prefix
Cygdrive default prefix:
Build date: Sat Jul 2 20:30:04 EDT 2005
Shared id: cygwin1S4
-------------- next part --------------
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/time.h>
class CCounter
{
public:
CCounter()
: m_iCount(0)
{ pthread_mutex_init(&m_Mutex, 0); pthread_cond_init(&m_Cond, 0); }
~CCounter()
{ pthread_cond_destroy(&m_Cond); pthread_mutex_destroy(&m_Mutex); }
void WaitUntilAtLeast(int const i)
{ pthread_mutex_lock(&m_Mutex);
while (m_iCount < i)
pthread_cond_wait(&m_Cond, &m_Mutex);
pthread_mutex_unlock(&m_Mutex); }
void operator++()
{ pthread_mutex_lock(&m_Mutex); m_iCount++;
pthread_cond_signal(&m_Cond);
pthread_mutex_unlock(&m_Mutex); }
private:
pthread_mutex_t m_Mutex;
pthread_cond_t m_Cond;
int m_iCount;
};
static volatile int s_iIterations;
static volatile pthread_t s_Thread1ID;
static volatile pthread_t s_Thread2ID;
static volatile timeval s_iTime[1000];
static CCounter s_ThreadsStarted;
void* Thread1(void*)
{
++s_ThreadsStarted;
s_ThreadsStarted.WaitUntilAtLeast(2);
sigset_t EmptyMask;
sigemptyset(&EmptyMask);
for (int i = 0; i < s_iIterations; i++)
{
gettimeofday(const_cast<timeval*>(&s_iTime[2*i]), 0);
pthread_kill(s_Thread2ID, SIGALRM);
sigsuspend(&EmptyMask);
}
return 0;
}
void* Thread2(void*)
{
++s_ThreadsStarted;
s_ThreadsStarted.WaitUntilAtLeast(2);
sigset_t EmptyMask;
sigemptyset(&EmptyMask);
sigsuspend(&EmptyMask);
for (int i = 0; i < s_iIterations; i++)
{
gettimeofday(const_cast<timeval*>(&s_iTime[2*i+1]), 0);
pthread_kill(s_Thread1ID, SIGALRM);
sigsuspend(&EmptyMask);
}
return 0;
}
void SignalHandler(int const /*iSignal*/)
{
// write(STDOUT_FILENO, "SIGALRM\n", 8);
}
int main(int argc, char** argv)
{
sigset_t BlockedSignals;
sigemptyset(&BlockedSignals);
sigaddset(&BlockedSignals, SIGALRM);
sigprocmask(SIG_BLOCK, &BlockedSignals, 0);
struct sigaction Sigaction;
memset(&Sigaction, 0, sizeof(Sigaction));
Sigaction.sa_handler = SignalHandler;
sigaction(SIGALRM, &Sigaction, 0);
s_iIterations = (argc > 1) ? atoi(argv[1]) : 5;
std::cout << "Iterations: " << s_iIterations << "\n";
pthread_create(const_cast<pthread_t*>(&s_Thread1ID), 0, Thread1, 0);
pthread_create(const_cast<pthread_t*>(&s_Thread2ID), 0, Thread2, 0);
pthread_join(s_Thread1ID, 0);
pthread_kill(s_Thread2ID, SIGALRM);
pthread_join(s_Thread2ID, 0);
for (int i = 1; i < 2 * s_iIterations; i++)
{
timeval Delta;
timersub(&s_iTime[i], &s_iTime[i-1], &Delta);
std::cout << i << ' ' << Delta.tv_usec * 1e-3 << " ms\n";
}
{
timeval Timeval1;
timeval Timeval2;
timeval Delta;
gettimeofday(&Timeval1, 0);
gettimeofday(&Timeval2, 0);
timersub(&Timeval2, &Timeval1, &Delta);
std::cout << "Time required for one gettimeofday() call: "
<< Delta.tv_usec * 1e-3 << " ms\n";
}
return 0;
}
// Local variables:
// compile-command: "g++ -Wall -W -g -O3 ctxtsw.cpp -o ctxtsw -lpthread"
// End:
-------------- next part --------------
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
More information about the Cygwin
mailing list