POSIX specifies that siginfo_t.si_addr must be void*. OpenBSD currently
defines it as caddr_t. This breaks some userspace programs, such as the
following minimal case:

  #include <signal.h>
  #include <iostream>

  void handler(int, siginfo_t *info, void*) {
      std::cout << "Foo" << info->si_addr << "bar\n";
  }

  int main(int, char**) {
      struct sigaction action;
      action.sa_sigaction = handler;
      action.sa_flags = SA_SIGINFO;
      sigaction(SIGILL, &action, NULL);

      raise(SIGILL);
      return 0;
  }

On OpenBSD, ostream will treat the char* si_addr as a C-string. Luckily
it's NULL in this case, but it causes only "Foo" to be printed. No
future uses of std::cout will result in output.

The following patch builds the base system cleanly on x86_64, and
resolves the problem.

diff --git a/src/sys/sys/siginfo.h b/src/sys/sys/siginfo.h
index 814e8f2..1e8365f 100644
--- a/src/sys/sys/siginfo.h
+++ b/src/sys/sys/siginfo.h
@@ -150,7 +150,7 @@ typedef struct {
                        } _pdata;
                } _proc;
                struct {        /* SIGSEGV, SIGBUS, SIGILL and SIGFPE */
-                       caddr_t _addr;          /* faulting address */
+                       char    *_addr;         /* faulting address */
                        int     _trapno;        /* illegal trap number */
                } _fault;
 #if 0

-- Andrew Aldridge

Reply via email to