시그널 핸들러를 몇번 수행하다가 시스템이 죽습니다.ㅠ.ㅠ 고수님들 조언 부탁드립니다.

thewarparty의 이미지

디바이스 드라이버에서 특정 프로세스에게 주기적인 signal을 보내려고 함니다.

근데 시그널 핸들러를 몇번 수행 하다가 시스템이 죽는 현상이 발생합니다. ㅠ

제가 초보라 무엇이 문제인지 잘 모르겠습니다 .

고수님들의 많은 조언 부탁드립니다 .

아래는 소스코드입니다.

/////////////////////////////// 디바이스 드라이버

시그널을 보내기위해서 해당 프로세스의 정보를 가지고 오려는 ioctl 입니다.
int ioctltest_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) {

ioctl_test_info ctrl_info;
int size;
size = _IOC_SIZE( cmd );
printk("size %d\n", size);
switch(cmd) {

case IOCTLTEST_WRITE :
copy_from_user ( (void *) &ctrl_info, (const void *) arg, size );
user_pid = (pid_t *)ctrl_info.size;
printk("user pid number %d\n", user_pid);

user_struct = find_task_by_pid(user_pid);
printk("OK\n");
check_number =1;

break;
}

return 0;
}

struct file_operations ioctltest_fops = {

.owner = THIS_MODULE,
.ioctl = ioctltest_ioctl,
.open = ioctltest_open,
.release = ioctltest_release,

};

......................................

// 여기서 해당 프로세스에게 시그널을 보냅니다.

static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
if (check_number == 1 )
{
force_sig(SIGUSR1, user_struct);
//send_sig_info(SIGUSR2,(struct siginfo *)1 ,user_struct);
}
else
{
printk(" signal send not user process \n");
}

return 0;

}

///////////////////////////////////////////////시그널을 받을 유저 프로세스

#include
#include
#include
#include
#include
#include
#include
#include
#include "test.h"
#include
#define name "/dev/test"
struct task_struct *task;
int a =1;

void test_handler()
{

printf(" %d\n", a++);

}

int main()
{
int fd;
int ret,i;
ioctl_test_info info;
struct task_struct *p;

/* sh
struct sigaction usrsig;
usrsig.sa_handler = test_handler;
sigemptyset(&usrsig.sa_mask);
usrsig.sa_flags = 0;
*/

fd = open(name,O_RDWR|O_NDELAY);
i = signal(SIGUSR1, (void *)test_handler); //////////////////
printf("fd : %d\n", fd);

info.size = getpid();
printf(" pid %d \n", info.size);

ioctl(fd, IOCTLTEST_WRITE , &info.size);
printf( " signal ok %d\n", i);

while (1){

}

close(fd);
return 0;
}

원더맨의 이미지

궁금해서 대충 만들어, 주기적으로 signal 을 user process 로 보내는거 테스트해봤는데, 전 아무이상없이 signal_handler 가 동작하는군요.
아마 다른 부분에 문제가 있을 거 같네요. 차근차근 보면 해결하실수 있으실거 같아요.

echo $user_pid > /sys/kernel/foo/foo
 
static int foo_thread(void *data)
{
    struct pid *pid;
    struct task_struct *user_task;
 
    while (!kthread_should_stop()) {
        msleep(500);
        if (user_pid > 0) {
             pid = find_get_pid(user_pid);
             user_task = get_pid_task(pid, PIDTYPE_PID);
             if (user_task) {
                  printk("send sig to %d\n", user_pid);
                  force_sig(SIGUSR1, user_task);
             }
        }
 
    }
}

밥굶지말자

thewarparty의 이미지

감사합니다.!! 다시 뒤져보고 해야 겠네요..ㅠ

죄송하지만 하나만 더 물어봐도 될까요??

혹시 시그널 핸들러에서 printf()를 써서 값이 제대로 찍히셨는지 궁금합니다.

원더맨의 이미지

#define HZ      (1000000)
 
static void sig_handler(int sig)
{
        printf("%s\n", __func__);
}
 
int main(int argc, char *argv[])
{
        struct sigaction sa;
 
        sa.sa_handler = sig_handler;
        sigaction(SIGUSR1, &sa, NULL);
 
        printf("pid = %d\n", getpid());
 
        while (1) {
                printf("I'm alive\n");
                usleep(HZ);
        }
        return 0;
}

밥굶지말자

jick의 이미지

시그널 핸들러에서는 원래 printf 쓰면 안됩니다. 프로그램의 정상동작을 보장할 수 없습니다.

시그널 핸들러에서 안심하고 쓸 수 있는 함수는 대단히 제한되어 있습니다. 혹시 Stevens의 Advanced programming in the UNIX environment 책 있으시면 Signal 챕터에서 Reentrant functions를 찾아보시기 바랍니다. (2판 기준으로 306쪽이네요. 아마 1판에도 있을 것 같은데...)

원더맨의 이미지

오.. 그러네요. 까먹고 있었는데 상기시켜주셔서 감솨합니다.

밥굶지말자

svperbeast의 이미지

https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers

sigwait() 같은 함수들에 대해서도 알아보시면 도움이 될 것 같습니다..

thewarparty의 이미지

감사합니다.

개념을 잘 모르고 있어서 여기저기서 헤매었는데 공부를 더 해봐야 할 것 같습니다.ㅠ.ㅠ

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.