This is an archive of the discontinued LLVM Phabricator instance.

Don't try to redefine the signal() function on Windows
ClosedPublic

Authored by zturner on Mar 18 2016, 3:53 PM.

Details

Summary

Windows comes with an extremely limited implementation of signal which only supports a few signal values. Of importance to LLDB is the SIGINT value which invokes a callback when the user presses Ctrl+C. For some reason, we were completely redefining the signal() function to intercept SIGINT and use our own custom processing of Ctrl+C rather than use the builtin processing of Ctrl+C done by signal(). This is frought with peril for a number of reasons:

  1. Depending on order of includes, you could get into a situation where both builtin signal() and our own custom signal() are defined, leading to multiply defined symbol errors at link time.
  2. It leads to a bunch of compiler warnings, since we end up redefining the same constants (e.g. SIG_DFL etc) because we were going through hoops to avoid #including the standard headers (even though that doesn't work)
  3. The standard implementation of signal() actually does exactly what you would expect it to do with regards to Ctrl+C. In fact, by looking at the source code of the CRT, you can see that for SIGINT it actually just calls SetConsoleCtrlHandler, which is exactly what our own custom implementation of signal did!

So, we simply remove all of our custom windows versions of signal() and use the builtin implementation. Code that attempts to call signal() with values that are not supported on Windows are handled by preprocessor defines

Diff Detail

Repository
rL LLVM

Event Timeline

zturner updated this revision to Diff 51082.Mar 18 2016, 3:53 PM
zturner retitled this revision from to Don't try to redefine the signal() function on Windows.
zturner updated this object.
zturner added reviewers: amccarth, cameron314.
zturner added a subscriber: lldb-commits.
zturner updated this revision to Diff 51090.Mar 18 2016, 4:17 PM

Update with context

cameron314 edited edge metadata.Mar 18 2016, 4:20 PM

Cool! I got pulled into something else at work and didn't have time to investigate the linker error that this led to, sorry. But the patch looks good to me (not that I know LLDB very well).

tools/driver/Driver.cpp
1314 ↗(On Diff #51082)

Might be slightly more portable to use _WIN32 to detect the OS platform instead of detecting the compiler?

tools/driver/Platform.cpp
93–97 ↗(On Diff #51082)

It looks like MIDriverMain.cpp was using this. Will it continue to work without the console control handler?

tools/driver/Platform.h
15 ↗(On Diff #51082)

This comment is no longer relevant.

amccarth edited edge metadata.Mar 18 2016, 4:26 PM

I like where this is going. Just a couple concerns.

tools/driver/Platform.h
15 ↗(On Diff #51090)

delete this comment

40 ↗(On Diff #51090)

Now that we are including <signal.h>, won't the following defines create duplicate definition warnings for the non-Windows platforms?

tools/lldb-mi/Platform.h
73 ↗(On Diff #51090)

As in the other file, now that we're including <signal.h>, I think the following definitions may be unnecessary and might cause compile-time warnings for non-Windows systems.

zturner added inline comments.Mar 18 2016, 4:26 PM
tools/driver/Driver.cpp
1314 ↗(On Diff #51090)

I think _MSC_VER is the right check, because the builtin signal implementation is something that is part of Visual Studio. If you were using Cygwin I imagine some of those constants might be present (although tbh, I don't ever use Cygwin and I don't know if anyone else does either, so someone would need to confirm).

_MSC_VER is also defined for clang-cl, so this check would catch MSVC and clang-cl

tools/driver/Platform.cpp
93–97 ↗(On Diff #51090)

Yes, because now MIDriverMain.cpp should end up calling the builtin version of signal(), which also calls SetConsoleCtrlHandler. As far as I can tell there's no actual difference (technically, the builtin version is a strict superset of this version, so if anything it should be better)

zturner added inline comments.Mar 18 2016, 4:28 PM
tools/lldb-mi/Platform.h
73 ↗(On Diff #51090)

No, because Windows doesn't define them in the first place. Windows only defines the 5 or 6 values it supports. These are here so as to avoid having to fix up the remaining 10-20 locations and wrap them in pre-processor definitions. signal() will just return an error if called with these values, but it's no different than the old implementation where we simply ignored the values by way of a switch statement that did nothing.

amccarth accepted this revision.Mar 18 2016, 4:31 PM
amccarth edited edge metadata.

looks good

This revision is now accepted and ready to land.Mar 18 2016, 4:31 PM
cameron314 added inline comments.Mar 18 2016, 4:34 PM
tools/driver/Driver.cpp
1314 ↗(On Diff #51090)

I was thinking more of mingw-w64, which tries very hard to have a compatible set of headers as those defined in the Windows SDK (and does not define _MSC_VER). But many, many other places in LLDB already check _MSC_VER anyway.

tools/driver/Platform.cpp
93–97 ↗(On Diff #51090)

Great!

tools/driver/Platform.h
40 ↗(On Diff #51090)

It's only included on Windows, though -- unless some other TU includes both this header and signal.h?

This revision was automatically updated to reflect the committed changes.
lldb/trunk/tools/lldb-mi/Platform.h