Skip to content

Commit

Permalink
Add backtraces to examples (#5973)
Browse files Browse the repository at this point in the history
* examples: Log stack trace on exceptions

For now, this is only implemented on Windows.
This helps to address #5520.

* examples: Print log file if there is any

* format code

---------

Co-authored-by: slangbot <[email protected]>
Co-authored-by: Yong He <[email protected]>
  • Loading branch information
3 people authored Jan 8, 2025
1 parent c43f6fa commit 5b99314
Show file tree
Hide file tree
Showing 22 changed files with 324 additions and 33 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci-examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ function run_sample {
pushd "$bin_dir" 1>/dev/null 2>&1
if [[ ! "$dry_run" = true ]]; then
./"$sample" "${args[@]}" || result=$?
if [[ -f ./"log-$sample.txt" ]]; then
cat ./"log-$sample.txt"
fi
fi
if [[ $result -eq 0 ]]; then
summary=("${summary[@]}" " success")
Expand Down
23 changes: 23 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
function(example dir)
cmake_parse_arguments(ARG "WIN32_EXECUTABLE" "" "" ${ARGN})

set(debug_dir ${CMAKE_CURRENT_BINARY_DIR}/${dir})

file(
Expand Down Expand Up @@ -30,6 +32,22 @@ function(example dir)
)
endif()

# Libraries providing a main function that prints stack traces on exceptions
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
# On Windows we have two different versions: main for "console applications" and
# WinMain for normal Windows applications.
if(${ARG_WIN32_EXECUTABLE})
set(main_wrapper_libraries example-winmain)
else()
set(main_wrapper_libraries example-main)
endif()
# Add stack printing support
set(main_wrapper_libraries ${main_wrapper_libraries} stacktrace-windows)
set(main_wrapper_libraries ${main_wrapper_libraries} dbghelp.lib)
else()
set(main_wrapper_libraries example-main)
endif()

slang_add_target(
${dir}
EXECUTABLE
Expand All @@ -42,7 +60,9 @@ function(example dir)
gfx-util
platform
$<$<BOOL:${SLANG_ENABLE_CUDA}>:CUDA::cuda_driver>
${main_wrapper_libraries}
EXTRA_COMPILE_DEFINITIONS_PRIVATE
SLANG_EXAMPLE_NAME=${dir}
$<$<BOOL:${SLANG_ENABLE_XLIB}>:SLANG_ENABLE_XLIB>
REQUIRED_BY all-examples
OPTIONAL_REQUIRES ${copy_assets_target} copy-prebuilt-binaries
Expand All @@ -68,6 +88,9 @@ if(SLANG_ENABLE_EXAMPLES)
$<$<BOOL:${SLANG_ENABLE_CUDA}>:CUDA::cuda_driver>
FOLDER examples
)
slang_add_target(example-main STATIC FOLDER examples)
slang_add_target(example-winmain STATIC FOLDER examples EXCLUDE_FROM_ALL)
slang_add_target(stacktrace-windows STATIC FOLDER examples EXCLUDE_FROM_ALL)

add_custom_target(
all-examples
Expand Down
2 changes: 1 addition & 1 deletion examples/autodiff-texture/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,4 +823,4 @@ struct AutoDiffTexture : public WindowedAppBase
}
};

PLATFORM_UI_MAIN(innerMain<AutoDiffTexture>)
EXAMPLE_MAIN(innerMain<AutoDiffTexture>);
2 changes: 1 addition & 1 deletion examples/cpu-com-example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ static SlangResult _innerMain(int argc, char** argv)
return SLANG_OK;
}

int main(int argc, char** argv)
int exampleMain(int argc, char** argv)
{
return SLANG_SUCCEEDED(_innerMain(argc, argv)) ? 0 : -1;
}
2 changes: 1 addition & 1 deletion examples/cpu-hello-world/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static SlangResult _innerMain(int argc, char** argv)
return SLANG_OK;
}

int main(int argc, char** argv)
int exampleMain(int argc, char** argv)
{
return SLANG_SUCCEEDED(_innerMain(argc, argv)) ? 0 : -1;
}
13 changes: 13 additions & 0 deletions examples/example-base/example-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@
void _Win32OutputDebugString(const char* str);
#endif

#define SLANG_STRINGIFY(x) #x
#define SLANG_EXPAND_STRINGIFY(x) SLANG_STRINGIFY(x)

#ifdef _WIN32
#define EXAMPLE_MAIN(innerMain) \
extern const char* const g_logFileName = \
"log-" SLANG_EXPAND_STRINGIFY(SLANG_EXAMPLE_NAME) ".txt"; \
PLATFORM_UI_MAIN(innerMain);

#else
#define EXAMPLE_MAIN(innerMain) PLATFORM_UI_MAIN(innerMain)
#endif // _WIN32

struct WindowedAppBase : public TestBase
{
protected:
Expand Down
32 changes: 32 additions & 0 deletions examples/example-main/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "../stacktrace-windows/common.h"

#include <stdio.h>
#include <stdlib.h>

extern int exampleMain(int argc, char** argv);

#if defined(_WIN32)

#include <windows.h>

int main(int argc, char** argv)
{
__try
{
return exampleMain(argc, argv);
}
__except (exceptionFilter(stdout, GetExceptionInformation()))
{
::exit(1);
}
}

#else // defined(_WIN32)

int main(int argc, char** argv)
{
// TODO: Catch exception and print stack trace also on non-Windows platforms.
return exampleMain(argc, argv);
}

#endif
28 changes: 28 additions & 0 deletions examples/example-winmain/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "../stacktrace-windows/common.h"

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

extern int exampleMain(int argc, char** argv);
extern const char* const g_logFileName;

int WinMain(
HINSTANCE /* instance */,
HINSTANCE /* prevInstance */,
LPSTR /* commandLine */,
int /*showCommand*/)

{
FILE* logFile = fopen(g_logFileName, "w");
__try
{
int argc = 0;
char** argv = nullptr;
return exampleMain(argc, argv);
}
__except (exceptionFilter(logFile, GetExceptionInformation()))
{
::exit(1);
}
}
2 changes: 1 addition & 1 deletion examples/gpu-printing/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ struct ExampleProgram : public TestBase
}
};

int main(int argc, char* argv[])
int exampleMain(int argc, char** argv)
{
ExampleProgram app;
if (SLANG_FAILED(app.execute(argc, argv)))
Expand Down
3 changes: 2 additions & 1 deletion examples/hello-world/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ struct HelloWorldExample : public TestBase
~HelloWorldExample();
};

int main(int argc, char* argv[])

int exampleMain(int argc, char** argv)
{
initDebugCallback();
HelloWorldExample example;
Expand Down
2 changes: 1 addition & 1 deletion examples/model-viewer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,4 +969,4 @@ struct ModelViewer : WindowedAppBase

// This macro instantiates an appropriate main function to
// run the application defined above.
PLATFORM_UI_MAIN(innerMain<ModelViewer>)
EXAMPLE_MAIN(innerMain<ModelViewer>);
2 changes: 1 addition & 1 deletion examples/nv-aftermath-example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,4 +599,4 @@ void AftermathCrashExample::renderFrame(int frameBufferIndex)

// This macro instantiates an appropriate main function to
// run the application defined above.
PLATFORM_UI_MAIN(innerMain<AftermathCrashExample>)
EXAMPLE_MAIN(innerMain<AftermathCrashExample>)
2 changes: 1 addition & 1 deletion examples/platform-test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,4 @@ struct PlatformTest : public WindowedAppBase

// This macro instantiates an appropriate main function to
// run the application defined above.
PLATFORM_UI_MAIN(innerMain<PlatformTest>)
EXAMPLE_MAIN(innerMain<PlatformTest>);
2 changes: 1 addition & 1 deletion examples/ray-tracing-pipeline/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,4 +712,4 @@ struct RayTracing : public WindowedAppBase

// This macro instantiates an appropriate main function to
// run the application defined above.
PLATFORM_UI_MAIN(innerMain<RayTracing>)
EXAMPLE_MAIN(innerMain<RayTracing>);
2 changes: 1 addition & 1 deletion examples/ray-tracing/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,4 +676,4 @@ struct RayTracing : public WindowedAppBase

// This macro instantiates an appropriate main function to
// run the application defined above.
PLATFORM_UI_MAIN(innerMain<RayTracing>)
EXAMPLE_MAIN(innerMain<RayTracing>);
2 changes: 1 addition & 1 deletion examples/reflection-api/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1469,7 +1469,7 @@ struct ExampleProgram : public TestBase
}
};

int main(int argc, char* argv[])
int exampleMain(int argc, char** argv)
{
ExampleProgram app;
if (SLANG_FAILED(app.execute(argc, argv)))
Expand Down
2 changes: 1 addition & 1 deletion examples/shader-object/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ Result loadShaderProgram(
}

// Main body of the example.
int main(int argc, char* argv[])
int exampleMain(int argc, char** argv)
{
testBase.parseOption(argc, argv);

Expand Down
2 changes: 1 addition & 1 deletion examples/shader-toy/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,4 @@ struct ShaderToyApp : public WindowedAppBase

// This macro instantiates an appropriate main function to
// run the application defined above.
PLATFORM_UI_MAIN(innerMain<ShaderToyApp>)
EXAMPLE_MAIN(innerMain<ShaderToyApp>);
Loading

0 comments on commit 5b99314

Please sign in to comment.