pthread_getschedparam函数
来源:互联网 发布:mac软件免费下载平台 编辑:程序博客网 时间:2024/06/11 09:53
昨天在工作中遇到了一个问题,在linux2.4.*的系统中调用pthread_getschedparam函数时,第一个参数指定为0系统不宕,
而在linux2.6的内核中调用该函数,第一个参数指定为0,则系统宕,原因是收到了SIGSEVG信号,也就是说程序访问的非法的地址。查了一晚上,应该是找到原因了。
首先看pthread_getschedparam函数的定义。
/*
* sched_getschedparam.c
*
* Description:
* POSIX thread functions that deal with thread scheduling.
*
* --------------------------------------------------------------------------
*
* Pthreads-win32 - POSIX Threads Library for Win32
* Copyright(C) 1998 John E. Bossom
* Copyright(C) 1999,2005 Pthreads-win32 contributors
*
* Contact Email: rpj@callisto.canberra.edu.au
*
* The current list of contributors is contained
* in the file CONTRIBUTORS included with the source
* code distribution. The list can also be seen at the
* following World Wide Web location:
* http://sources.redhat.com/pthreads-win32/contributors.html
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library in the file COPYING.LIB;
* if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "pthread.h"
#include "implement.h"
#include "sched.h"
int
pthread_getschedparam (pthread_t thread, int *policy,
struct sched_param *param)
{
int result;
/* Validate the thread id. */
result = pthread_kill (thread, 0);
if (0 != result)
{
return result;
}
/*
* Validate the policy and param args.
* Check that a policy constant wasn't passed rather than &policy.
*/
if (policy <= (int *) SCHED_MAX || param == NULL)
{
return EINVAL;
}
/* Fill out the policy. */
*policy = SCHED_OTHER;
/*
* This function must return the priority value set by
* the most recent pthread_setschedparam() or pthread_create()
* for the target thread. It must not return the actual thread
* priority as altered by any system priority adjustments etc.
*/
param->sched_priority = ((ptw32_thread_t *)thread.p)->sched_priority;
return 0;
}
函数首先调用了pthread_kill函数,在查一下pthread_kill的定义。
/** Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
02
This file is part of the GNU C Library.
03
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
04
05
The GNU C Library is free software; you can redistribute it and/or
06
modify it under the terms of the GNU Lesser General Public
07
License as published by the Free Software Foundation; either
08
version 2.1 of the License, or (at your option) any later version.
09
10
The GNU C Library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
14
15
You should have received a copy of the GNU Lesser General Public
16
License along with the GNU C Library; if not, write to the Free
17
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
02111-1307 USA. */
19
20
#include <errno.h>
21
#include <signal.h>
22
#include <pthreadP.h>
23
#include <tls.h>
24
#include <sysdep.h>
25
#include <kernel-features.h>
26
27
28
int
29
__pthread_kill (threadid, signo)
30
pthread_t threadid;
31
int
signo;
32
{
33
struct
pthread *pd = (
struct
pthread *) threadid;
34
35
/** Make sure the descriptor is valid. */
36
if
(DEBUGGING_P && INVALID_TD_P (pd))
37
/** Not a valid thread handle. */
38
return
ESRCH;
39
40
/** Force load of pd->tid into local variable or register. Otherwise
41
if a thread exits between ESRCH test and tgkill, we might return
42
EINVAL, because pd->tid would be cleared by the kernel. */
43
pid_t tid = atomic_forced_read (pd->tid);
44
if
(__builtin_expect (tid <= 0, 0))
45
/** Not a valid thread handle. */
46
return
ESRCH;
47
48
/** Disallow sending the signal we use for cancellation, timers, for
49
for the setxid implementation. */
50
if
(signo == SIGCANCEL || signo == SIGTIMER || signo == SIGSETXID)
51
return
EINVAL;
52
53
/** We have a special syscall to do the work. */
54
INTERNAL_SYSCALL_DECL (err);
55
56
/** One comment: The PID field in the TCB can temporarily be changed
57
(in fork). But this must not affect this code here. Since this
58
function would have to be called while the thread is executing
59
fork, it would have to happen in a signal handler. But this is
60
no allowed, pthread_kill is not guaranteed to be async-safe. */
61
int
val;
62
#if __ASSUME_TGKILL
63
val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
64
tid, signo);
65
#else
66
# ifdef __NR_tgkill
67
val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
68
tid, signo);
69
if
(INTERNAL_SYSCALL_ERROR_P (val, err)
70
&& INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
71
# endif
72
val = INTERNAL_SYSCALL (tkill, err, 2, tid, signo);
73
#endif
74
75
return
(INTERNAL_SYSCALL_ERROR_P (val, err)
76
? INTERNAL_SYSCALL_ERRNO (val, err) : 0);
77
}
78
strong_alias (__pthread_kill, pthread_kill)
从中可以看到,在pthread_kill中,
if (DEBUGGING_P && INVALID_TD_P (pd))
37
/** Not a valid thread handle. */
38
return
ESRCH;
首先进行了判断,但是很有可能DEBUGGING_P宏没定义,所以程序就跳了过去,
然后再43
pid_t tid = atomic_forced_read (pd->tid);