Skip to content

Comments

Add SIGKILL to PosixSignal enumeration#124256

Merged
adamsitnik merged 14 commits intomainfrom
copilot/extend-posixsignal-enumeration
Feb 12, 2026
Merged

Add SIGKILL to PosixSignal enumeration#124256
adamsitnik merged 14 commits intomainfrom
copilot/extend-posixsignal-enumeration

Conversation

Copy link
Contributor

Copilot AI commented Feb 11, 2026

Description

Extends PosixSignal with SIGKILL = -11. SIGKILL cannot be caught or ignored per POSIX semantics - the OS enforces this naturally by throwing appropriate exceptions when registration is attempted.

Changes

  • Enumeration: Added PosixSignal.SIGKILL = -11 with [UnsupportedOSPlatform("windows")] and XML doc "Kill (cannot be caught or ignored)"
  • Ref assembly: Added SIGKILL = -11 entry with [UnsupportedOSPlatformAttribute("windows")]
  • Native layer: Updated pal_signal.{h,c} to map SIGKILL in GetPlatformSignalNumber and TryConvertSignalCodeToPosixSignal
  • OS-level validation: No explicit validation in managed code - the OS handles SIGKILL registration attempts naturally:
    • Unix: OS throws IOException when trying to enable signal handling for SIGKILL
    • Windows: Throws PlatformNotSupportedException (SIGKILL not in supported signals)
  • Tests: Added PosixSignal.SIGKILL to UninstallableSignals() on Unix; excluded SIGKILL from SupportedSignals, PosixSignalAsRawValues, and ProcessTests.SignalTestData() test data

Contributes to #123380


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

Copilot AI and others added 2 commits February 11, 2026 07:58
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copilot AI changed the title [WIP] Extend PosixSignal enumeration with SIGKILL value Add SIGKILL to PosixSignal enumeration with registration validation Feb 11, 2026
Copilot AI requested a review from adamsitnik February 11, 2026 08:02
Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot please address my feedback

Per feedback from @adamsitnik, moved SIGKILL validation from the Unix-specific
Register method to the platform-agnostic Create method. The validation now checks
both the SIGKILL enum value (-11) and the raw POSIX signal number (9), ensuring
SIGKILL cannot be registered on any platform. Removed the s_sigkillNumber field
as it's no longer needed.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 11, 2026

@copilot please address my feedback

Feedback addressed in commit b421171. Moved SIGKILL validation from Unix-specific Register method to platform-agnostic Create method, and removed the s_sigkillNumber field.

Copilot AI and others added 2 commits February 11, 2026 08:23
Replaced magic number 9 with SIGKILL_POSIX_SIGNAL_NUMBER constant
for better code clarity and maintainability.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Updated comment to clarify that we check both PosixSignal.SIGKILL (-11)
and raw signal number 9 cast to enum type (e.g., (PosixSignal)9).

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Per feedback from @jkotas and @adamsitnik:
- Changed exception from ArgumentException to IOException to match OS behavior
- Removed check for raw signal number (9) - let OS throw IOException naturally
- Only check PosixSignal.SIGKILL enum value to provide better error message
- Updated test to expect IOException instead of ArgumentException
- Removed unused SIGKILL_POSIX_SIGNAL_NUMBER constant

This avoids a breaking change where the exception type would differ for
raw signal numbers vs enum values.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot please address my feedback

Per feedback from @jkotas and @adamsitnik:
- Removed SIGKILL check from platform-agnostic Create method
- Removed Arg_CannotRegisterHandlerForSIGKILL resource string
- Let OS-specific Register methods throw naturally:
  - Unix: IOException from OS when trying to enable signal handling
  - Windows: PlatformNotSupportedException (SIGKILL not in switch)
- Updated tests to be platform-specific:
  - Unix test expects IOException
  - Windows test expects PlatformNotSupportedException

This allows the OS to handle validation naturally without adding
extra checks that provide no value.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 11, 2026

@copilot please address my feedback

Feedback addressed in commit fb5b0ac.

Copilot AI changed the title Add SIGKILL to PosixSignal enumeration with registration validation Add SIGKILL to PosixSignal enumeration Feb 11, 2026
@stephentoub
Copy link
Member

stephentoub commented Feb 11, 2026

@adamsitnik, at the moment this doesn't add any benefit, right? It's only once we add the ability to send a PosixSignal that this becomes meaningful? And at that point we'll update consumers like Process.Kill() to use this instead of P/Invoking directly? (The correctness of the mapping / handling of this value would be easier if the sending ability were introduced first.)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the System.Runtime.InteropServices.PosixSignal public API to include SIGKILL and wires it through the native System.Native signal mapping so it can be converted to/from platform signal numbers, along with updating unit tests to reflect SIGKILL’s non-registrable semantics.

Changes:

  • Added PosixSignal.SIGKILL = -11 (Windows-unsupported) to the public enum and reference assembly.
  • Updated System.Native PAL (pal_signal.h/.c) to map SIGKILL in both conversion directions.
  • Updated PosixSignalRegistration unit tests to ensure SIGKILL registration throws and to exclude SIGKILL from “supported/registrable” datasets.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/native/libs/System.Native/pal_signal.h Adds PosixSignalSIGKILL = -11 to the native enum.
src/native/libs/System.Native/pal_signal.c Maps SIGKILL in TryConvertSignalCodeToPosixSignal and SystemNative_GetPlatformSignalNumber.
src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs Adds SIGKILL to the reference assembly enum surface area.
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/PosixSignal.cs Adds SIGKILL to the runtime enum with XML doc + platform annotation.
src/libraries/System.Runtime.InteropServices/tests/.../PosixSignalRegistrationTests.Unix.cs Adds Unix-only SIGKILL throw test and removes SIGKILL from registrable test data.
src/libraries/System.Runtime.InteropServices/tests/.../PosixSignalRegistrationTests.Windows.cs Adds Windows SIGKILL throw test.

Per @jkotas feedback: add PosixSignal.SIGKILL to UninstallableSignals()
on Unix so it's covered by Create_UninstallableSignal_Throws, and delete
the explicit Create_SIGKILL_Throws tests from both Unix and Windows files
(the Windows test was redundant with Create_InvalidSignal_Throws). Also
remove the now-unnecessary 'using System.IO;' directive from the Unix file.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
@jkotas
Copy link
Member

jkotas commented Feb 11, 2026

And at that point we'll update consumers like Process.Kill() to use this instead of P/Invoking directly?

The Process interop uses SIGKILL and SIGSTOP:

While this can replace uses of SIGKILL, we do not have a SIGSTOP. Also, the hardcoded 19 for SIGSTOP Is non-portable. Should we add SIGSTOP (and SIGCONT for parity) to the public API too?

@adamsitnik
Copy link
Member

@adamsitnik, at the moment this doesn't add any benefit, right? It's only once we add the ability to send a PosixSignal that this becomes meaningful? And at that point we'll update consumers like Process.Kill() to use this instead of P/Invoking directly? (The correctness of the mapping / handling of this value would be easier if the sending ability were introduced first.)

For me the main benefit is having the other upcoming PRs smaller and easier to review. Then we will just focus on sending the signals, not ensuring that existing APIs can't sign up for SIGKILL like in this PR.

I'll try to do better in upcoming PRs.

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (as an incremental step towards implementing full API proposal)

@jkotas
Copy link
Member

jkotas commented Feb 11, 2026

For me the main benefit is having the other upcoming PRs smaller and easier to review

I personally prefer smaller PRs like this one (when it is well understood what we are working towards)

@stephentoub
Copy link
Member

For me the main benefit is having the other upcoming PRs smaller and easier to review

I personally prefer smaller PRs like this one (when it is well understood what we are working towards)

I do as well, but I prefer it further when they're "complete". My preference would have been to first add the send API, which could be fully tested (and possibly used in various places). Then this PR would be able to actually validate that the signal mapping is working correctly by using that send API in a test to kill a child process, and could also be consumed in places like Process. It's still smaller, but it's more end-to-end.

That said, we can go ahead with this one.

@jkotas
Copy link
Member

jkotas commented Feb 12, 2026

@copilot Failing test

Unhandled Exception:
System.IO.IOException: Invalid argument
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirError) in /_/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs:line 16
   at Interop.ThrowIOExceptionForLastError() in /_/src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs:line 53
   at System.Runtime.InteropServices.PosixSignalRegistration.Register(PosixSignal signal, Action`1 handler) in /_/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/PosixSignalRegistration.Unix.cs:line 47
   at System.Runtime.InteropServices.PosixSignalRegistration.Create(PosixSignal signal, Action`1 handler) in /_/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/PosixSignalRegistration.cs:line 42
   at System.Diagnostics.Tests.ProcessTests.<>c.<TestCreateNewProcessGroup_HandlerReceivesExpectedSignal>b__6_0(String signalStr) in /_/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs:line 124
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args) in /_/src/mono/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.Mono.cs:line 22
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr) in /_/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs:line 174

SIGKILL cannot be caught or ignored, so iterating all PosixSignal enum
values to register handlers fails for SIGKILL with IOException. Skip it
in the test data, consistent with how SIGKILL is excluded from
SupportedSignals in PosixSignalRegistrationTests.

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 12, 2026

@copilot Failing test

Unhandled Exception:

...

Fixed in commit 4813de4. ProcessTests.SignalTestData() iterates Enum.GetValues<PosixSignal>() which now includes SIGKILL. Added a skip for PosixSignal.SIGKILL since it cannot be caught or ignored.

Copilot AI requested a review from jkotas February 12, 2026 01:40
@adamsitnik
Copy link
Member

/ba-g the build failure is #124322, which got already fixed in main

@adamsitnik adamsitnik merged commit 2690e0f into main Feb 12, 2026
160 of 168 checks passed
@adamsitnik adamsitnik deleted the copilot/extend-posixsignal-enumeration branch February 12, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants