You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

170 lines
9.7 KiB

/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
namespace Magnum {
/** @page troubleshooting Troubleshooting
@brief Various tricks and solutions to common pitfalls.
@tableofcontents
@m_footernavigation
@section troubleshooting-building Building issues
If your project suddenly stops building after a Magnum upgrade, check these
things:
- If building fails on the CMake step, be sure that you have up-to-date
`FindCorrade.cmake`, `FindMagnum.cmake` and other CMake modules in your
project (`FindSDL2.cmake`, ...). They are contained in `modules/` directory
of Magnum repositories and also get installed into `share/cmake/Magnum`.
- In very rare cases the CMake build directory may not survive an upgrade. If
you get some particularly cursed errors, try recreating it from scratch.
- The library is constantly evolving, meaning that APIs may get deprecated
and removed over time. If you upgrade to a version that deprecated a
particular API you use, the code will emit a deprecation warning,
suggesting a migration path. Except for rare cases, the deprecated APIs are
guaranteed to stay in the codebase for a year at least (or two subsequent
version releases, whichever is longer) and only then they get removed. To
make sure you're no longer using any deprecated functionality, it's
possible to disable the `MAGNUM_BUILD_DEPRECATED`
@ref building-features "CMake option" when building Magnum, although for a
smoother experience it's recommended to flip this option back on when
upgrading. A list of deprecated APIs is maintained
@ref changelog-latest-deprecated "in the changelog".
- In some rare cases, it's impossible to provide a deprecated migration path
and an API gets changed in a backwards-incompatible manner, directly
leading to a compile error. Another possibility is that transitive header
dependencies got cleaned up for @ref compilation-forward-declarations "speeding up compilation" and you're now missing an @cpp #include @ce. The major
compatiblity breakages are always listed @ref changelog-latest-compatibility "in the changelog".
- If you upgrade from a really old release, it's recommended to gradually
upgrade over tagged versions of Magnum and not jumping directly to latest
version. That way you're more likely to follow the deprecation path,
instead of directly ending up with long-deprecated APIs being gone with no
direct way to know what should be used instead. If in doubt, browse the
@ref changelog "old changelogs".
@section troubleshooting-runtime Runtime issues
Magnum makes heavy use of assertions to catch programmer errors (as opposed to
runtime or data-dependent errors, which get handled in more graceful ways), and
because past experience showed their usefulness, majority of assertions is
@ref CORRADE_NO_ASSERT "by default kept even in release builds".
If your application abruptly exits, it's important to know whether it was a
regular *exit*, an *abort* or a *crash*, as each of these may point to a
different problem.
- Except for crashes, in which case the application usually won't even have a
chance to complain about anything, you should get a message on the standard
error output:
- On Unix systems the output can be seen when running from a console
- On Windows, if you don't see the console, switch the build back to a
console app @ref platform-windows-hiding-console "instead of a GUI app"
--- in case of CMake you can temporarily remove the `WIN32` part from
your @cmake add_executable() @ce call
- On Android @ref platforms-android-output-redirection "you can use logcat"
- On Emscripten the output is printed to the browser console
- A regular exit may happen during startup due to an error in arguments
passed on the command line, or when a window / context creation fails. The
error output should mention what happened.
- An abort is an assertion failure, with the error message telling you why.
It's an abort in order to trigger a debugger break (or the assertion dialog
on Windows) or create a core dump (on Unix systems) so you can see the
backtrace leading to the error.
- One of the more frequent assertion messages is
@cb{.shell-session} GL::Context::current(): no current context @ce.
This happens when you try to use OpenGL functionality when the OpenGL
context is not yet created (or no longer exists). See
@ref opengl-wrapping-instances-nocreate for more information.
- A crash is usually a memory issue. To find the root cause, by far the
easiest is to hook up AddressSanitizer (`-fsanitize=address` on GCC, Clang
and [recent MSVC](https://docs.microsoft.com/en-us/cpp/sanitizers/asan)).
It can detect out-of-bounds accesses, use-after-free, leaks and other
issues and upon discovering a problem it prints a lengthy diagnostic about
what happened, where does the memory come from and what code touched it and
how.
@section troubleshooting-opengl OpenGL issues
If you are experiencing the so-called "black screen of death", weird behavior
or crashes on GL calls, you might want to try these things:
- Enable @ref GL::DebugOutput "debug output" to see more detailed errors,
warnings and performance hints. You can do that easily through the
`--magnum-gpu-validation` @ref GL-Context-usage-command-line "command-line option"
or an environment variable.
- If you are on Mac, the native OpenGL implementation doesn't support
this. Instead you can manually verify that
@ref GL::Renderer::error() "no OpenGL error was emitted".
- Check that you use only extensions that are
@ref GL::Context::isExtensionSupported() "available on your system".
- Check that you didn't exceed any implementation-defined limit (see
@ref magnum-gl-info output for a list of all of them).
- If using framebuffer objects,
@ref GL::Framebuffer::checkStatus() "check that they are complete".
- Rendering to three-component @ref GL::TextureFormat works on some GPUs
but not others. TO avoid platform-dependent issues, always use one-,
two- or four-component formats.
- Change @ref GL::Renderer::setClearColor() "framebuffer clear color" to
something else than black to verify that at least something is drawn. The
engine sets it to @cpp 0x1f1f1f_rgbf @ce by default to help you a bit in
this regard.
- If nothing is drawn, use @ref GL::PrimitiveQuery to check that at least
some primitives were generated. Use @ref GL::SampleQuery to check whether
fragments were drawn.
- Verify that the mesh is properly set up --- nonzero vertex/index count,
matching type in buffer and @ref GL::Mesh::addVertexBuffer() "vertex specification",
properly set up @ref GL::Mesh::setIndexBuffer() "index buffer" and index
count for indexed mesh. If you specified index range, be sure that all
indices fall into it, otherwise you would get undefined behavior.
- Try disabling the @ref GL::Renderer::Feature::DepthTest "depth test",
@ref GL::Renderer::Feature::FaceCulling "face culling" and other renderer
features that might cause fragments to be discarded.
- Verify that your projection and transformation matrix is properly set up
--- try drawing points instead of triangles, to see if they are in proper
places at least.
- For custom shaders you can @ref GL::AbstractShaderProgram::validate() "Validate them".
Check that all used uniforms and attributes have proper locations. Try
reducing it until it is able to draw something, possibly also with some
simpler mesh.
- Magnum tracks the OpenGL state to improve performance, but the tracker can
get confused if you or any other library are doing OpenGL calls outside of
Magnum. For that to work, you need to
@ref opengl-state-tracking "reset the state tracker" on boundaries between
3rd party and Magnum calls into GL. The other library also needs to be
aware of this fact (either setting all state explicitly every time or
having similar ability to reset its state tracker), otherwise you may need
to save and restore GL state manually for that library to work.
@subsection troubleshooting-opengl-debugging Debugging rendering
- Use @ref GL::TimeQuery to find hot spots in the rendering code.
- @ref GL::DebugMessage::insert() "Mark relevant parts of code" to find them
easier in the debugger.
- Use ApiTrace or RenderDoc to trace the program call by call, verify buffer
and texture contents, vertex binding and count of generated primitives,
rendered fragments and time spent in various calls.
*/
}