diff --git a/steam-runtime-tools/graphics.c b/steam-runtime-tools/graphics.c index 05fd8f9e50d756249c3b093592abb4f6aa6dcefe..cf6bf9e377162c3377b9a3d0909bf25fec8cb2aa 100644 --- a/steam-runtime-tools/graphics.c +++ b/steam-runtime-tools/graphics.c @@ -31,6 +31,7 @@ #include "steam-runtime-tools/utils-internal.h" #include <string.h> +#include <sys/wait.h> #include <json-glib/json-glib.h> @@ -305,6 +306,14 @@ _srt_check_graphics (const char *helpers_path, g_return_val_if_reached (SRT_GRAPHICS_ISSUES_INTERNAL_ERROR); } + // Use timeout command to limit how long the helper can run + g_ptr_array_add (argv, g_strdup ("timeout")); + g_ptr_array_add (argv, g_strdup ("--signal=TERM")); + // Kill the helper after 3 seconds + g_ptr_array_add (argv, g_strdup ("--kill-after=3")); + // Send TERM signal after 1 second + g_ptr_array_add (argv, g_strdup ("10")); + if (rendering_interface == SRT_RENDERING_INTERFACE_GL) { if (helpers_path != NULL) @@ -367,6 +376,14 @@ _srt_check_graphics (const char *helpers_path, { g_debug ("... wait status %d", exit_status); issues |= SRT_GRAPHICS_ISSUES_CANNOT_LOAD; + + // TERM signal gives us 124 from timeout man page + if (WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 124) // timeout command killed the helper + { + g_debug ("helper killed by timeout command"); + issues |= SRT_GRAPHICS_ISSUES_TIMEOUT; + } + goto out; } diff --git a/steam-runtime-tools/graphics.h b/steam-runtime-tools/graphics.h index 22de98fb6e90fae3dda18316435dfa3b72eb4662..ec9130e7833c7492d0d70959393ea4c855eda1c1 100644 --- a/steam-runtime-tools/graphics.h +++ b/steam-runtime-tools/graphics.h @@ -63,6 +63,7 @@ typedef enum SRT_GRAPHICS_ISSUES_INTERNAL_ERROR = (1 << 0), SRT_GRAPHICS_ISSUES_CANNOT_LOAD = (1 << 1), SRT_GRAPHICS_ISSUES_SOFTWARE_RENDERING = (1 << 2), + SRT_GRAPHICS_ISSUES_TIMEOUT = (1 << 3), } SrtGraphicsIssues; /** diff --git a/tests/graphics.c b/tests/graphics.c index 979f69e76a9e5f5de3bfe7188415cd99d86099b3..2e173d8ae95b0d14558c6b0694dfcac9200dc365 100644 --- a/tests/graphics.c +++ b/tests/graphics.c @@ -200,6 +200,53 @@ test_bad_graphics (Fixture *f, g_object_unref (info); } +/* + * Test a mock system with timeout + */ +static void +test_timeout_graphics (Fixture *f, + gconstpointer context) +{ + SrtGraphics *graphics = NULL; + SrtGraphicsIssues issues; + gchar *tuple; + gchar *renderer; + gchar *version; + + SrtSystemInfo *info = srt_system_info_new (NULL); + srt_system_info_set_helpers_path (info, f->builddir); + + issues = srt_system_info_check_graphics (info, + "mock-hanging", + SRT_WINDOW_SYSTEM_GLX, + SRT_RENDERING_INTERFACE_GL, + &graphics); + g_debug ("issues is %d", issues); + g_assert ((issues & SRT_GRAPHICS_ISSUES_CANNOT_LOAD) == SRT_GRAPHICS_ISSUES_CANNOT_LOAD); + g_assert ((issues & SRT_GRAPHICS_ISSUES_TIMEOUT) == SRT_GRAPHICS_ISSUES_TIMEOUT); + g_assert_cmpstr (srt_graphics_get_renderer_string (graphics), ==, + NULL); + g_assert_cmpstr (srt_graphics_get_version_string (graphics), ==, + NULL); + g_object_get (graphics, + "multiarch-tuple", &tuple, + "issues", &issues, + "renderer-string", &renderer, + "version-string", &version, + NULL); + g_assert ((issues & SRT_GRAPHICS_ISSUES_CANNOT_LOAD) == SRT_GRAPHICS_ISSUES_CANNOT_LOAD); + g_assert ((issues & SRT_GRAPHICS_ISSUES_TIMEOUT) == SRT_GRAPHICS_ISSUES_TIMEOUT); + g_assert_cmpstr (tuple, ==, "mock-hanging"); + g_assert_cmpstr (renderer, ==, NULL); + g_assert_cmpstr (version, ==, NULL); + g_free (tuple); + g_free (renderer); + g_free (version); + + g_object_unref (graphics); + g_object_unref (info); +} + /* * Test a mock system with software rendering */ @@ -257,6 +304,8 @@ main (int argc, setup, test_good_graphics, teardown); g_test_add ("/bad", Fixture, NULL, setup, test_bad_graphics, teardown); + g_test_add ("/hanging", Fixture, NULL, + setup, test_timeout_graphics, teardown); g_test_add ("/software", Fixture, NULL, setup, test_software_rendering, teardown); diff --git a/tests/meson.build b/tests/meson.build index dced9536b74f49c8e0b75175950506dbeb1feefc..6be1274c98e249bbe610916321f6115782f3c0cf 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -145,6 +145,13 @@ executable( install_dir : tests_dir ) +executable( + 'mock-hanging-wflinfo', + 'mock-hanging-wflinfo.c', + install: true, + install_dir: tests_dir +) + executable( 'mock-bad-wflinfo', 'mock-bad-wflinfo.c', diff --git a/tests/mock-hanging-wflinfo.c b/tests/mock-hanging-wflinfo.c new file mode 100644 index 0000000000000000000000000000000000000000..50aae91f08776323fd3bbba8d5aa3b485ca085bf --- /dev/null +++ b/tests/mock-hanging-wflinfo.c @@ -0,0 +1,48 @@ +/* + * Copyright © 2019 Collabora Ltd. + * + * SPDX-License-Identifier: MIT + * + * 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. + */ + +#include <stdio.h> +#include <unistd.h> + +#include "../steam-runtime-tools/graphics-test-defines.h" + +int +main (int argc, + char **argv) +{ + sleep (300); // Sleep for 5 minutes + + // then give good output + printf ("{\n\t\"waffle\": {\n\t\t\"platform\": \"glx\",\n\t\t\"api\": \"gl\"\n\t},\n\t\"OpenGL\": {\n\t\t\"vendor string\": \"Intel Open Source Technology Center\",\n" + "\t\t\"renderer string\": \"" + SRT_TEST_GOOD_GRAPHICS_RENDERER + "\",\n\t\t\"version string\": \"" + SRT_TEST_GOOD_GRAPHICS_VERSION + "\",\n\t\t\"shading language version string\": \"1.30\",\n" + "\t\t\"extensions\": [\n" + "\t\t]\n\t}\n}\n"); + return 0; +} +