7a3e4054c7
It turns out this was already enabled on MSVC (due to /EHsc), but let's enable it on other platforms as well. Exception handling comes with a huge caveat: SourceMod and SourcePawn are not exception safe. Not only do they predate usable STL (C++11), they often predate C++03, and sometimes even C++ itself. There are many places we do not use RAII, or where we accumulate state in a way that cannot be interrupted. By enabling exceptions, we are NOT inviting general try/catch. We are still assuming that a `throw` anywhere within SourceMod will ultimately result in a crash. However, as we enable more and more STL, we are losing the ability to gracefully handle constructor failures and malloc failures. So try-catch is now enabled. It should only be used in the narrowest of circumstances: - When an exception can be thrown by a library call, and - There is no way "a priori" to tell if an exception will be thrown (for example, std::bad_alloc or std::system_error), and - Handling the exception is meaningful. Generally malloc failures should not be considered meaningful. Once memory is exhausted, the program will crash or be OOM-killed, so there's no point in handling the failure. However, cases where the allocation amount is variable may be meaningful to handle. A simple example would be CDataPack, where if a plugin leaks entries, it's better to handle this gracefully given that vector growth is geometric. Another example might be reads of a massive file or network request into a buffer. These cases should be rare, given that memory pressure is usually fatal to srcds anyway. But if you've decided to handle an exception, the try-catch block should be as narrow as possible. For example, the following is erroneous: ke::Maybe<SomeGiganticThing> object; try { object.init(); } catch (const std::bad_alloc&) { } `ke::Maybe` is not threadsafe, and this can leak. Basically, do as little as possible in try blocks, and use them sparingly, because they're very difficult to audit. We are also not inviting use of `throw`, as auditing it is even more complex than try/catch. It is better to abort(), or use boolean returns and two-stage object initialization. |
||
---|---|---|
.github | ||
bridge/include | ||
configs | ||
core | ||
editor | ||
extensions | ||
gamedata | ||
licenses | ||
loader | ||
plugins | ||
public | ||
sourcepawn@2075605089 | ||
tools | ||
translations | ||
versionlib | ||
.arcconfig | ||
.gitattributes | ||
.gitignore | ||
.gitmodules | ||
.travis.yml | ||
AMBuildScript | ||
changelog.txt | ||
configure.py | ||
product.version | ||
pushbuild.txt | ||
README.md |
SourceMod
General
- SourceMod website: Source Engine scripting and server administration
- Forum: Discussion forum including plugin/extension development
- General documentation: Miscellaneous information about SourceMod
- Stable builds: The latest stable SourceMod releases
- Dev builds: Builds of recent development versions
Development
- Issue tracker: Issues that require back and forth communication
- Building SourceMod: Instructions on how to build SourceMod itself using AMBuild
- SourcePawn scripting: SourcePawn examples and introduction to the language
- SourceMod plugin API: Online SourceMod plugin API reference generated from the include files
- SourceMod extension development: C++ examples and introduction to various extension interfaces
Contact
License
SourceMod is licensed under the GNU General Public License version 3. Special exceptions are outlined in the LICENSE.txt file inside of the licenses folder.