簡體   English   中英

后台進程的信號處理

[英]Signal handling for background processes

我正在嘗試在C中實現一個簡單的Unix shell。但是,我無法通過使用sigaction來實現后台進程功能。 我的代碼結構如下:

int main() {
struct sigaction act;
act.sa_handler = handler;

sigaction(SIGCHLD, &act, 0);

while(1) {
    parseCommand();
    execCommand();
}
}

另外,在我的execCommand函數中,結構如下:

if (fork()) {
    if (!isBackground) {
        wait(&child_status);
    }
    else
    printf("Background process\n");
}
else
    ... // Command execution...

我的處理程序如下:

void handler(int s) {
while (waitpid(-1, NULL, WNOHANG) > 0) {
}
printf("OK.\n");
}

但這種結構損害了我的整個實施。 甚至前台進程都無法正常工作。 當我執行前台命令時,它給出:

Segmentation fault (core dumped) 

當我執行后台命令時,它給出:

Bus error (core dumped)

那么,我該如何解決這個問題呢?

提前致謝...

編輯:當我用valgrind調試我的代碼時,它給出以下內容:

==6768== Memcheck, a memory error detector
==6768== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6768== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==6768== Command: ./shell
==6768== 
==6768== Syscall param rt_sigaction(act->sa_mask) points to uninitialised byte(s)
==6768==    at 0x4E6F5AE: __libc_sigaction (sigaction.c:62)
==6768==    by 0x400E90: main (in /home/enes/Desktop/Shell/shell)
==6768==  Address 0xffefff908 is on thread 1's stack
==6768== 
==6768== Syscall param rt_sigaction(act->sa_flags) points to uninitialised byte(s)
==6768==    at 0x4E6F5AE: __libc_sigaction (sigaction.c:62)
==6768==    by 0x400E90: main (in /home/enes/Desktop/Shell/shell)
==6768==  Address 0xffefff8f8 is on thread 1's stack
==6768== 
> ls
==6768== Use of uninitialised value of size 8
==6768==    at 0x4EA8C80: _IO_getline_info (iogetline.c:77)
==6768==    by 0x4EA7B7C: fgets (iofgets.c:53)
==6768==    by 0x400EC9: main (in /home/enes/Desktop/Shell/shell)
==6768== 
==6768== Invalid write of size 1
==6768==    at 0x4EA8C80: _IO_getline_info (iogetline.c:77)
==6768==    by 0x4EA7B7C: fgets (iofgets.c:53)
==6768==    by 0x400EC9: main (in /home/enes/Desktop/Shell/shell)
==6768==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6768== 
==6768== 
==6768== Process terminating with default action of signal 11 (SIGSEGV)
==6768==  Access not within mapped region at address 0x0
==6768==    at 0x4EA8C80: _IO_getline_info (iogetline.c:77)
==6768==    by 0x4EA7B7C: fgets (iofgets.c:53)
==6768==    by 0x400EC9: main (in /home/enes/Desktop/Shell/shell)
==6768==  If you believe this happened as a result of a stack
==6768==  overflow in your program's main thread (unlikely but
==6768==  possible), you can try to increase the size of the
==6768==  main thread stack using the --main-stacksize= flag.
==6768==  The main thread stack size used in this run was 8388608.
==6768== 
==6768== HEAP SUMMARY:
==6768==     in use at exit: 0 bytes in 0 blocks
==6768==   total heap usage: 2 allocs, 2 frees, 2,048 bytes allocated
==6768== 
==6768== All heap blocks were freed -- no leaks are possible
==6768== 
==6768== For counts of detected and suppressed errors, rerun with: -v
==6768== Use --track-origins=yes to see where uninitialised values come from
==6768== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
 Syscall param rt_sigaction(act->sa_mask) points to uninitialised byte(s) 

您需要完全初始化sigaction結構,否則它包含不確定的值。 讀取那些(可能是通過sigaction()函數調用)可能會導致未定義的行為 ,從中可以發生任何事情。

要修復此更改

struct sigaction act;

成為

struct sigaction act = {0};

可能不是你面臨的問題,但仍然:

從信號處理程序調用printf() - 函數的任何成員都不能保存

更多:可以安全地從信號處理程序調用的函數集(非常)受限。 有關完整列表,請參閱本頁的第2.4.3章

要修復此更改

printf("OK.\n");

成為

write(STDERR_FILENO, "OK.\n", sizeof "OK.\n" -1);

或者一樣的。 根據上面鏈接的列表, write()保存為從信號處理程序調用。


 ==6768== Use of uninitialised value of size 8 ==6768== at 0x4EA8C80: _IO_getline_info (iogetline.c:77) ==6768== by 0x4EA7B7C: fgets (iofgets.c:53) 

fgets()的調用實際上有什么問題我們無法分辨,因為你沒有向我們展示相關的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM