Linux信号-1-TIF_SIGPENDING 标志的设置和清除
基于msm-5.4
一、调用路径
1. 设置的位置
recalc_sigpending_and_wake //signal.c sysrq_term_op //sysrq.c 【】-e 操作结束所有进程 echo e > /proc/sysrq-trigger sysrq_handle_term //sysrq.c sysrq_kill_op //sysrq.c 【】 -i选项,kill掉所有进程 echo i > /proc/sysrq-trigger sysrq_handle_kill //sysrq.c send_sig_all //sysrq.c 对所有进程进行调用 __do_notify //mqueue.c 没编译到 hwpoison_user_mappings //memory-failure.c 【】内存操作失败kill掉进程 memory_failure_dev_pagemap //memory-failure.c kill_procs //memory-failure.c kill_fasync_rcu //fcntl.c send_sigio //fcntl.c send_sigio_to_task //fcntl.c send_sigurg //fcntl.c send_sigurg_to_task //fcntl.c group_send_sig_info //signal.c oom_kill_memcg_member //oom_kill.c 【】对所有进程发送 SIGKILL 信号 oom_kill_process //oom_kill.c __oom_kill_process //oom_kill.c send_sig //signal.c send_sig_fault //signal.c send_sig_mceerr //signal.c aa_audit //audit.c __raise_exception //f_mass_storage.c send_sig_info //signal.c do_send_specific //signal.c do_send_sig_info //signal.c __group_send_sig_info //signal.c force_sig_info_to_task //signal.c ptrace_signal //signal.c kdb_send_sig //signal.c send_signal //signal.c kill_pid_usb_asyncio //signal.c do_notify_parent //signal.c __send_signal //signal.c alarm_handle_timer //alarmtimer.c cpu_timer_fire //posix-cpu-timers.c posix_timer_fn //posix-timers.c posix_timer_event //posix-timers.c send_sigqueue //signal.c complete_signal //signal.c zap_other_threads //signal.c do_signal_stop //signal.c retarget_shared_pending //signal.c cgroup_freeze_task //freezer.c freeze_task //freezer.c fake_signal_wake_up //freezer.c zap_process //coredump.c signal_wake_up //signal.h ptrace_signal_wake_up //signal.h ptrace_attach //ptrace.c signal_wake_up_state //signal.c 设置标志位并唤醒任务 set_tsk_thread_flag(t, TIF_SIGPENDING)
设置的位置一共有:
recalc_sigpending_tsk //signal.c set_tsk_thread_flag(t, TIF_SIGPENDING); calculate_sigpending //signal.c set_tsk_thread_flag(current, TIF_SIGPENDING) signal_wake_up_state //signal.c 先主要看这个 set_tsk_thread_flag(t, TIF_SIGPENDING)
2. clear的位置
ret_from_fork //entry.S 【】新fork的任务唤醒时会清除信号pending标志 schedule_tail(prev) //core.c calculate_sigpending //signal.c SYSCALL_DEFINE4(signalfd4 //signalfd.c SYSCALL_DEFINE3(signalfd //signalfd.c do_compat_signalfd4 //signalfd.c do_signalfd4 //signalfd.c signalfd_fops //signalfd.c signalfd_read //signalfd.c signalfd_dequeue //signalfd.c handle_exception //usb/f_mass_storage.c jffs2_garbage_collect_thread //jffs2/background.c kernel_dequeue_signal //signal.h ret_to_user //arm64/entry.S【】返回用户空间信号被处理后pending标志会被清除 ### work_pending //arm64/entry.S do_notify_resume //signal.c do_signal //signal.c get_signal //signal.c SYSCALL_DEFINE4(rt_sigtimedwait //signal.c 【】系统调用中有清理逻辑 SYSCALL_DEFINE4(rt_sigtimedwait_time32 //signal.c COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait_time64 //signal.c do_sigtimedwait //signal.c dequeue_signal //signal.c get_signal //signal.c dequeue_synchronous_signal //signal.c user_single_step_report //ptrace.h seccomp_send_sigsys //seccomp.c force_sig //signal.c force_sig_mceerr //signal.c force_sig_bnderr //signal.c force_sig_pkuerr //signal.c force_sig_ptrace_errno_trap //signal.c force_sig_info //signal.c arm64_notify_die //traps.c bad_el0_sync //traps.c single_step_handler //debug-monitors.c brk_handler //debug-monitors.c send_user_sigtrap //debug-monitors.c arm64_force_sig_fault //arm64/kernel/traps.c force_sig_fault //signal.c user_enable_single_step //ptrace.c force_sig_fault_to_task //signal.c force_sig_info_to_task //signal.c get_signal //signal.c 上面已经有调用路径了 __set_task_blocked //signal.c do_sigtimedwait //signal.c allow_signal //signal.h 【】内核有自己的信号逻辑!!! allow_kernel_signal //signal.h disallow_signal //signal.h call_usermodehelper_setup //umh.c call_usermodehelper_setup_file //umh.c call_usermodehelper_exec_work //umh.c call_usermodehelper_exec_sync //umh.c kernel_sigaction //signal.c copy_process //fork.c 【】创建任务时会清理pending信号标志 recalc_sigpending //signal.c clear_thread_flag(TIF_SIGPENDING)
clear信号的位置还有:
flush_signals //signal.c clear_tsk_thread_flag(t, TIF_SIGPENDING); do_freezer_trap clear_thread_flag(TIF_SIGPENDING) __exit_signal(tsk) //exit.c clear_tsk_thread_flag(tsk, TIF_SIGPENDING); zap_pid_ns_processes //pid_namespace.c clear_thread_flag(TIF_SIGPENDING); cgroup_leave_frozen set_thread_flag(TIF_SIGPENDING); zap_threads clear_tsk_thread_flag(tsk, TIF_SIGPENDING); clear_thread_flag(TIF_SIGPENDING) //st33zp24.c __tty_check_change set_thread_flag(TIF_SIGPENDING); wait_for_tpm_stat //tpm_tis_core.c clear_thread_flag(TIF_SIGPENDING);
注1: signalfd 是用于 同步化信号处理 的机制,通过文件描述符将信号转化为可读事件。Android中只有这两个位置有使用:
# TDIR=/proc; let RSS=0; for P in `ls $TDIR | grep "^[0-9]"`; do echo $P; ls -l /proc/$P/fd | grep signalfd; done 1 //init进程 lrwx------ 1 root root 64 1970-01-01 12:11 6 -> anon_inode:[signalfd] 31265 //update_engine进程 lrwx------ 1 root root 64 2025-05-07 14:08 10 -> anon_inode:[signalfd]
注2:umh.c中提供的call user mode helper 功能,是内核态触发用户空间进程执行的核心机制(内核创建用户进程并执行),典型应用场景比如内核模块加载。
// kernel/module.c static int load_module(..., const char *modname) { char *argv[] = { "/sbin/modprobe", modname, NULL }; call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); }
3. 小结
看起来 TIF_SIGPENDING 标志位主要是在任务被信号唤醒时设置,在返回用户空间处理信号时恢复。
posted on 2025-05-20 21:39 Hello-World3 阅读(40) 评论(0) 收藏 举报