openjdk/jdk · warning

VM warning: the use of signal() and sigset() for signal cha

Error message

 VM warning: the use of signal() and sigset() for signal chaining was deprecated in version 16.0 and will be removed in a future release. Use sigaction() instead.

What it means

Deprecation notice from libjsig (the JDK's signal-chaining library, preloaded via LD_PRELOAD on Solaris/Linux HotSpot). If application or library code calls signal() or sigset() (instead of sigaction()) to install a signal handler while the JVM is running, libjsig intercepts the call, prints this one-time warning, and forwards the registration to the JVM's chained handling. Behavior is still correct; the API is deprecated because signal()'s unreliable semantics do not compose well with JVM signal chaining.

Source

Thrown at src/java.base/unix/native/libjsig/jsig.c:97

   * other than the jvm thread should wait. */
  if (jvm_signal_installing) {
    /* tid is not initialized until jvm_signal_installing is set to true. */
    if (pthread_equal(tid, pthread_self()) == 0) {
      do {
        pthread_cond_wait(&cond, &mutex);
      } while (jvm_signal_installing);
    }
  }
}

static void signal_unlock() {
  pthread_mutex_unlock(&mutex);
}

static void print_deprecation_warning() {
  if (!warning_printed) {
    warning_printed = true;
    fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() "
            "for signal chaining was deprecated in version 16.0 and will "
            "be removed in a future release. Use sigaction() instead.\n");
  }
}

static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
                                   bool is_sigset) {
  sa_handler_t res;

  if (os_signal == NULL) {
    if (!is_sigset) {
      os_signal = (signal_function_t)dlsym(RTLD_NEXT, "signal");
    } else {
      os_signal = (signal_function_t)dlsym(RTLD_NEXT, "sigset");
    }
    if (os_signal == NULL) {
      printf("%s\n", dlerror());
      exit(0);

View on GitHub (pinned to 88dfb74bbe)

Solutions

  1. Change the offending native code to install handlers with sigaction() instead of signal()/sigset() — this is the only real fix
  2. Identify the caller: run under a debugger with a breakpoint on signal(), or use tools like 'ltrace -e signal' to catch who calls it
  3. If the caller is a third-party library, upgrade to a version using sigaction or report it upstream
  4. The warning is printed only once per process; it is harmless unless the API is actually removed in a future release — plan the migration before then

Example fix

// before (C)
signal(SIGTERM, my_handler);

// after
struct sigaction sa;
sa.sa_handler = my_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
Defensive patterns

Strategy: validation

Validate before calling

// Audit native code linked into the process for deprecated calls before shipping:
//   ltrace -e signal -e sigset -- ./myapp 2>&1 | grep -v '^---'
// or link-time: nm -D libmynative.so | grep -w signal

Prevention

When it happens

Trigger: Any call to signal() or sigset() from JVM-attached native code (JNI library, agent, or the application itself) after libjsig was initialized. Typical sources: C libraries installing SIGINT/SIGTERM/SIGPIPE handlers, legacy code ported from older Unix codebases.

Common situations: Running a Java app that loads a third-party native library which registers signal handlers with signal(); using tools or daemons that call signal() during startup before/after JVM init; upgrading to JDK 16+ where the warning was introduced and seeing it in logs.

Related errors


AI-assisted analysis of openjdk/jdk@88dfb74bbe (2026-08-14). Data as JSON: /api/errors/87e3924b370e8621. Report an issue: GitHub.