아래에 select()에서 가끔 발생하는 세그먼트폴트에 대한 궁금증

익명 사용자의 이미지

왜 select()에서 세그먼트 폴트가 날까 아직도 고민중입니다..
얼마전에도 또 발생했네요..
평균 1주일에 한번꼴로 말이죠..

core파일을 볼때마다 느낀건데.. 항상 select()에서 죽더군요..
아래에도 말씀드렸지만 select()에서 지금까지 한건..
타이머기능밖에 없지요..

그래서 다른쪽으로 눈돌린것이.. 커널쪽입니다..
지금 커널을 업그레이드 할생각인데..

재가 현재 사용중인 커널이 2.4.2이지요.. 즉 7.1의 디폴트 커널이었습니
다. 그런데 생각난것이 2.4대 초기 버전은 버추얼 메모리에 버그가 있다
는 생각이 나더군요.. 혹 이와 관련된 문제가 아닐까라는 우매한 생각을
해봅니다.. 혹시 일말의 관련이라도 있지 않을까 지푸라기라도
잡는 심정으로...

아래에 여전히 답변이 없군요..
참 별짓을 다합니다..

만약 이렇게 해서라도 계속 같은데서 또 불규칙으로 죽는다면
BSD로 한번 OS를 체인지 하려고 합니다..

이 방법들이 오른지 모르겠네요.. 아 답답~~~

혹시 좀더 간단하고 쉽게 해결하는법이 있으면 알려주시면 감사드리겠습니
다. 그럼 꾸벅..

익명 사용자의 이미지

말씀만 듣고는 어렵습니다.

core 파일을 제 이메일로 주시면
원인을 분석해 보지요..

익명 사용자의 이미지

core파일이 장장 한 20-30메가가 넘어서 보내드릴수가 없네여 ^^
많게는 70메가가 넘나???
^^

아래에 3페이지째인가 아래에 재가..
gdb로 본 core를 그대로 카피엔 페이스트로 올려놨습니다..
select()가 사용된 펑션들두여...

그걸로 대체를 하면 안될까요??

이거 말고 아래에는 nanosleep()에서 죽었네여.,,. ^^
즉 왜 이런대서 죽냐 이건데...
계속 타이머로 사용하는부분만 다 죽네여 ㅠ.ㅠ
-----------------------------------------------------------------

Core was generated by `./LiveStudioStream'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libreadline.so.3...done.
Loaded symbols for /usr/lib/libreadline.so.3
Reading symbols from /lib/i686/libm.so.6...done.
Loaded symbols for /lib/i686/libm.so.6
Reading symbols from /lib/i686/libpthread.so.0...done.
[New Thread 1024 (LWP 7117)]
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/libtermcap.so.2...done.
Loaded symbols for /lib/libtermcap.so.2
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/libnss_files.so.2...done.
Loaded symbols for /lib/libnss_files.so.2
Reading symbols from /usr/lib/gconv/EUC-KR.so...done.
Loaded symbols for /usr/lib/gconv/EUC-KR.so
Reading symbols from /usr/lib/gconv/libKSC.so...done.
Loaded symbols for /usr/lib/gconv/libKSC.so
#0 0x4015a90e in __select () from /lib/i686/libc.so.6
(gdb)bt
#0 0x4015a90e in __select () from /lib/i686/libc.so.6
#1 0x400796d8 in __DTOR_END__ () from /lib/i686/libpthread.so.0
#2 0x4006bbfd in pthread_start_thread (arg=0x40800c00) at
manager.c262

익명 사용자의 이미지

malloc 해서 쓰는 메모리가 많은가보군요;;

음... backtrace로 알수 있는 정보는
죽은 지점 정도만 알수 있구요.

실제로 분석을 할려면,
스텍 프레임을 옮겨 다니면서 값들을 체크 해봐야 해요..
스텍 프레임을 옮겨 다는 것은
up, down 명령어가 있는데, 각 스택 프레임 별로
info local을 실행해서 로컬 변수의 상태를 봐야겠죠.

또 몇가지 체크 포인트가 있는데 core파일이 있으면
요런 분석이 쉬워지거든요;; 압축해서 웹서버나 ftp에
올려주시고 url을 메일로 알려주세요.

익명 사용자의 이미지

답변 감사 드립니다..
하지만 쩝.. 이거이 저희가 서비스하는 부분이라,.,
함부로 오픈을 하기가 힘드네요,.,.

죄송하지만 좀더 core파일가지고
어떻게 디버깅 하는지에 대한 방법을 저에게 알려주실수 없는지요,.,.
core에 관련된 디버깅 법에 관련된 자료가 있는곳을 알려주셔두 감사하구
요. 예전에도 찾아보았으나 쉽게 보이지가 않더군여..

그럼 답변 감사드리고 조은 하루 되세요..

익명 사용자의 이미지

gdb 사용법은..

http//www.gnu.org/manual/gdb-5.1.1/gdb.html
여기 메뉴얼만한게 없는것 같군요;;

근데 올리신 글을 보니 쓰레딩을 사용하시는거 같은데,
시그널이 문제가 될수 있습니다.

알람 종류들은 시그널을 사용하는데,
이 시그널이 멀티쓰레딩 환경에서는 그 알람을
셋팅한 쓰레드에서 받는게 아니란 거죠..;;
(누가 받을지 몰라요.. )

오렐리에서 나온 pthread 책중에서 시그널 처리에
관한 부분을 보시길 권합니다...

또 쓰레드 관리하기 위해서 pthread 라이브러리가
sigusr1 sigusr2를 사용하니 이 시그널을 사용하시는 것도 안됩니다.

http//pauillac.inria.fr/~xleroy/linuxthreads/faq.html
LinuxThreads Frequently Asked Questions
(with answers)
중에서 쓰레드와 시그널 관련글입니다.

J. Signals and threads
J.1 When it comes to signals, what is shared between
threads and what isn't?
Signal handlers are shared between all threads when a
thread calls sigaction(), it sets how the signal is handled
not only for itself, but for all other threads in the
program as well.
On the other hand, signal masks are per-thread each thread
chooses which signals it blocks independently of others. At
thread creation time, the newly created thread inherits the
signal mask of the thread calling pthread_create(). But
afterwards, the new thread can modify its signal mask
independently of its creator thread.

J.2 When I send a SIGKILL to a particular thread using
pthread_kill, all my threads are killed!
That's how it should be. The POSIX standard mandates that
all threads should terminate when the process (i.e. the
collection of all threads running the program) receives a
signal whose effect is to terminate the process (such as
SIGKILL or SIGINT when no handler is installed on that
signal). This behavior makes a lot of sense when you
type "ctrl-C" at the keyboard, or when a thread crashes on
a division by zero or a segmentation fault, you really want
all threads to stop immediately, not just the one that
caused the segmentation violation or that got the SIGINT
signal. (This assumes default behavior for those signals;
see question J.3 if you install handlers for those signals.)
If you're trying to terminate a thread without bringing the
whole process down, use pthread_cancel().

J.3 I've installed a handler on a signal. Which thread
executes the handler when the signal is received?
If the signal is generated by a thread during its execution
(e.g. a thread executes a division by zero and thus
generates a SIGFPE signal), then the handler is executed by
that thread. This also applies to signals generated by raise
().
If the signal is sent to a particular thread using
pthread_kill(), then that thread executes the handler.

If the signal is sent via kill() or the tty interface (e.g.
by pressing ctrl-C), then the POSIX specs say that the
handler is executed by any thread in the process that does
not currently block the signal. In other terms, POSIX
considers that the signal is sent to the process (the
collection of all threads) as a whole, and any thread that
is not blocking this signal can then handle it.

The latter case is where LinuxThreads departs from the
POSIX specs. In LinuxThreads, there is no real notion of
``the process as a whole'' in the kernel, each thread is
really a distinct process with a distinct PID, and signals
sent to the PID of a thread can only be handled by that
thread. As long as no thread is blocking the signal, the
behavior conforms to the standard one (unspecified) thread
of the program handles the signal. But if the thread to
which PID the signal is sent blocks the signal, and some
other thread does not block the signal, then LinuxThreads
will simply queue in that thread and execute the handler
only when that thread unblocks the signal, instead of
executing the handler immediately in the other thread that
does not block the signal.

This is to be viewed as a LinuxThreads bug, but I currently
don't see any way to implement the POSIX behavior without
kernel support.

J.3 How shall I go about mixing signals and threads in my
program?
The less you mix them, the better. Notice that all
pthread_* functions are not async-signal safe, meaning that
you should not call them from signal handlers. This
recommendation is not to be taken lightly your program can
deadlock if you call a pthread_* function from a signal
handler!
The only sensible things you can do from a signal handler
is set a global flag, or call sem_post on a semaphore, to
record the delivery of the signal. The remainder of the
program can then either poll the global flag, or use
sem_wait() and sem_trywait() on the semaphore.

Another option is to do nothing in the signal handler, and
dedicate one thread (preferably the initial thread) to wait
synchronously for signals, using sigwait(), and send
messages to the other threads accordingly.

J.4 When one thread is blocked in sigwait(), other threads
no longer receive the signals sigwait() is waiting for!
What happens?
It's an unfortunate consequence of how LinuxThreads
implements sigwait(). Basically, it installs signal
handlers on all signals waited for, in order to record
which signal was received. Since signal handlers are shared
with the other threads, this temporarily deactivates any
signal handlers you might have previously installed on
these signals.
Though surprising, this behavior actually seems to conform
to the POSIX standard. According to POSIX, sigwait() is
guaranteed to work as expected only if all other threads in
the program block the signals waited for (otherwise, the
signals could be delivered to other threads than the one
doing sigwait(), which would make sigwait() useless). In
this particular case, the problem described in this
question does not appear.

One day, sigwait() will be implemented in the kernel, along
with others POSIX 1003.1b extensions, and sigwait() will
have a more natural behavior (as well as better
performances).

익명 사용자의 이미지

좋은 정보 감사 드립니다...

참고로 재가 멀티 쓰레딩을 사용은 하나..
쓰레드 동기화나 이런것을 위해 알람을 사용하지 않습니다.

그리고 타이머도 단순히 nanosleep()과 select()만 사용하고 있지요..
즉 임의로 시그널을 발생을 시키지는 않습니다.

또 재가 간과하지 못한..
nanosleep()이나 select()함수가 시그널을 발생시킨다면 체크를 못하였을
수는 있으나..
man page를 보았어나 그런 얘기는 없습니다.
단순이 error handling에서만 나와있지요..

아고 머리 아풉니다 ㅠ.ㅠ

gdb로 본 결과로는 select()가 실행중에 죽는데..
재가 알기론 select()인 경우 시그널을 받으면
-1을 return하는것으로 알고 있습닏.,(errno와 함께요..)

아무튼 정말 감사합니다...
계속해서 core를 보면서 또 커널 또한 지금 재 컴파일 해서..
지금 곧 엎을 예정입니다..

아무튼 다른 좋은 충고 있으시면 언제던지 저에게 주시면 감사하겠습니다.

그럼 즐거운 하루 되세요..

익명 사용자의 이미지

sleep(), nanosleep()는 시그널을 사용하구요
select()는 시그널이랑은 무관하구요;;;

지금 세그멘테이션 폴트난 쓰레드가 원인이 아니라,
다른 쓰레드가 세그멘테이션 폴트난 쓰레드의
영역을 침범해서 문제가 될수도 있을듯 하군요..

아래는 시스템콜 트레이스 입니다.
=== sleep 사용시

close(3) = 0
mprotect(0x40074000, 970752, PROT_READ|PROT_WRITE) = 0
mprotect(0x40074000, 970752, PROT_READ|PROT_EXEC) = 0
personality(PER_LINUX) = 0
getpid() = 13634
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({10, 0}, {10, 0}) = 0
fstat64(0x1, 0xbffff0e0) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x40169000
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(1, "object is at 0xbffff8f0\n", 24object is at 0xbffff8f0) = 24
munmap(0x40169000, 4096) = 0
_exit(0) = ?

=== select 사용시

close(3) = 0
mprotect(0x40074000, 970752, PROT_READ|PROT_WRITE) = 0
mprotect(0x40074000, 970752, PROT_READ|PROT_EXEC) = 0
personality(PER_LINUX) = 0
getpid() = 13660
select(1, NULL, NULL, NULL, {5, 0}) = 0 (Timeout)
fstat64(0x1, 0xbffff0e0) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x40169000
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(1, "object is at 0xbffff8f0\n", 24object is at 0xbffff8f0) = 24
munmap(0x40169000, 4096) = 0
_exit(0) = ?

익명 사용자의 이미지

갑자기 궁금사항이 발생하였습니다..

warning Unable to set global thread event mask generic error
[New Thread 1024 (LWP 8837)]
Error while reading shared library symbols
Can't attach LWP 8837 No such process
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/libtermcap.so.2...done.
Loaded symbols for /lib/libtermcap.so.2
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/libnss_files.so.2...done.
Loaded symbols for /lib/libnss_files.so.2
Reading symbols from /usr/lib/gconv/EUC-KR.so...done.
Loaded symbols for /usr/lib/gconv/EUC-KR.so
Reading symbols from /usr/lib/gconv/libKSC.so...done.
Loaded symbols for /usr/lib/gconv/libKSC.so
#0 0x4015a90e in __select () from /lib/i686/libc.so.6
(gdb) bt
#0 0x4015a90e in __select () from /lib/i686/libc.so.6
#1 0x400796d8 in __DTOR_END__ () from /lib/i686/libpthread.so.0
#2 0x4006bbfd in pthread_start_thread (arg=0x41e90c00) at
manager.c262

보시면 pthread_start_thread라는 호출로 이어지면서 select()가
이루어지더군여..
그래서 재가 pthread_start_thread()부분을 어디서 호출하였나
했더니 없더군여..
아거 머리아퍼..

방금 님이 말씀하신 부분을 봤는데..
무슨얘기인지 정확히 이해가 안되네여..

좀더 두구 봐야겠지만.. 에혀 정말 힘드네여 ㅠ.ㅠ

어제 또다시 말썽을 일으켜서 중는줄 알았습니다..

흑흑 ㅠ.ㅠ

그리고 원래 세그먼트 폴트가 메모리영역의 침범으로 발생하는걸로 생각하

다른 쓰레드의 영역을 넘는바라메 발생하는걸로 추측은 하구여..
그런데 왜 항상 같은 부분인 select()에서 세그먼트폴트가 나는지 모르겠
네요. 즉 재가 만든 라이브러리에서 죽는다면 어떻게 해보겠으나..
이런 표준라이브러리나 glibc에서 나는지..
그리고 왜 비정기적으로 발생하는지..

위에서도 말했지만 지금 재가 사용하는 커널이 2.4.2입니다..
이 커널은 메모리 관리부분에 버그가 있는것으로 알고 있습니다.
혹시 이쪽이 아닐까.. 라는 생각으로 지금 커널을 2.4.18로 업 하려고합니
다. 이게 효용성이 있을지는 모르겠으나 시나 있을
1%확률도 없에고자 하는방법이지요..
즉 코드상의 문제일수두 있지만 현재 열시미 찾고 또 도움을 청하지만
뚜력한 해결책을 찾지 못하고 물론 앞으로 계쏙 찾을거지만..

에혀 이러다가 님한테 core파일 넘겨야 할거 같네여 ㅎㅎㅎㅎ
방법이나 좀 찾아봐야겠습니다..

앞으루두 답변 부탁 드리겠습니다 ^^*

참 그리고.. ICQ나 MSN사용하시면 알려주시면 감사하겠습니다..(앗 MSN은
내가 마스커레이딩 써서 파일 접송이 안되는구나 헉..)ICQ로 core파일을
보내드리겠습니다.

익명 사용자의 이미지

리눅스에서 쓰레드 pthread 라이브러리로 구현을
하고 있지요..

pthread_start_thread()는 pthread 라이브러리 함수 입니다.

자세한 것은
www.rpmfind.net에서
linuxthread란 패키지를 찾아보면 소스를 받아 보실수 있을껍니다.
우선 그 함수를 올려드리지요.

static int pthread_start_thread(void *arg)
{
pthread_descr self = (pthread_descr) arg;
struct pthread_request request;
void * outcome;
/* Initialize special thread_self processing, if any. */
#ifdef INIT_THREAD_SELF
INIT_THREAD_SELF(self, self->p_nr);
#endif
/* Make sure our pid field is initialized, just in case we get
there
before our father has initialized it. */
THREAD_SETMEM(self, p_pid, __getpid());
/* Initial signal mask is that of the creating thread. (Otherwise,
we'd just inherit the mask of the thread manager.) */
sigprocmask(SIG_SETMASK, &self->p_start_args.mask, NULL);
/* Set the scheduling policy and priority for the new thread, if
needed */
if (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
/* Explicit scheduling attributes were provided apply them */
__sched_setscheduler(THREAD_GETMEM(self, p_pid),
THREAD_GETMEM(self,
p_start_args.schedpolicy),
&self->p_start_args.schedparam);
else if (__pthread_manager_thread.p_priority > 0)
/* Default scheduling required, but thread manager runs in
realtime
scheduling switch new thread to SCHED_OTHER policy */
{
struct sched_param default_params;
default_params.sched_priority = 0;
__sched_setscheduler(THREAD_GETMEM(self, p_pid),
SCHED_OTHER, &default_params);
}
/* Make gdb aware of new thread */
if (__pthread_threads_debug && __pthread_sig_debug > 0) {
request.req_thread = self;
request.req_kind = REQ_DEBUG;
__libc_write(__pthread_manager_request,
(char *) &request, sizeof(request));
suspend(self);
}
/* Run the thread code */
outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,

p_start_args.arg));
/* Exit with the given return value */
pthread_exit(outcome);
return 0;
}

일딴 커널업도 해보시는 것도 좋을것 같네요..;;

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.