From: David Malcolm Date: Mon, 1 Dec 2014 15:58:11 +0000 (+0000) Subject: PR jit/63969: Fix segfault in error-handling when driver isn't found X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c985705ae91243bdabd4d828365017ef264bbd91;p=gcc.git PR jit/63969: Fix segfault in error-handling when driver isn't found gcc/jit/ChangeLog: PR jit/63969 * jit-playback.c: Ensure that ctxt_progname is non-NULL. gcc/testsuite/ChangeLog: PR jit/63969 * jit.dg/harness.h (CHECK_STRING_STARTS_WITH): New. (check_string_starts_with): New. * jit.dg/test-error-pr63969-missing-driver.c: New. From-SVN: r218226 --- diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index f0136b4d98b..9555e729dd7 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,8 @@ +2014-12-01 David Malcolm + + PR jit/63969 + * jit-playback.c: Ensure that ctxt_progname is non-NULL. + 2014-11-19 David Malcolm PR jit/63854 diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index 8fdfa29b0a0..584a8e63759 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -1571,9 +1571,11 @@ compile () /* Pass in user-provided program name as argv0, if any, so that it makes it into GCC's "progname" global, used in various diagnostics. */ ctxt_progname = get_str_option (GCC_JIT_STR_OPTION_PROGNAME); - fake_args[0] = - (ctxt_progname ? ctxt_progname : "libgccjit.so"); + if (!ctxt_progname) + ctxt_progname = "libgccjit.so"; + + fake_args[0] = ctxt_progname; fake_args[1] = m_path_c_file; num_args = 2; @@ -1689,6 +1691,9 @@ compile () /* pex argv arrays are NULL-terminated. */ argv[6] = NULL; + /* pex_one's error-handling requires pname to be non-NULL. */ + gcc_assert (ctxt_progname); + errmsg = pex_one (PEX_SEARCH, /* int flags, */ gcc_driver_name, const_cast (argv), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94ca3b6292f..d86e406ef3f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-12-01 David Malcolm + + PR jit/63969 + * jit.dg/harness.h (CHECK_STRING_STARTS_WITH): New. + (check_string_starts_with): New. + * jit.dg/test-error-pr63969-missing-driver.c: New. + 2014-12-01 David Malcolm * jit.dg/jit.exp (jit-dg-test): Use $name rathen than $prog diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h index f326891c56d..bff64de0201 100644 --- a/gcc/testsuite/jit.dg/harness.h +++ b/gcc/testsuite/jit.dg/harness.h @@ -81,6 +81,9 @@ static char test[1024]; #define CHECK_STRING_VALUE(ACTUAL, EXPECTED) \ check_string_value ((ACTUAL), (EXPECTED)); +#define CHECK_STRING_STARTS_WITH(ACTUAL, EXPECTED_PREFIX) \ + check_string_starts_with ((ACTUAL), (EXPECTED_PREFIX)); + #define CHECK(COND) \ do { \ if (COND) \ @@ -103,6 +106,10 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result); extern void check_string_value (const char *actual, const char *expected); +extern void +check_string_starts_with (const char *actual, + const char *expected_prefix); + /* Implement framework needed for turning the testcase hooks into an executable. test-combination.c and test-threads.c each combine multiple testcases into larger testcases, so we have COMBINED_TEST as a way of @@ -137,6 +144,30 @@ void check_string_value (const char *actual, const char *expected) pass ("%s: actual: NULL == expected: NULL"); } +void +check_string_starts_with (const char *actual, + const char *expected_prefix) +{ + if (!actual) + { + fail ("%s: actual: NULL != expected prefix: \"%s\"", + test, expected_prefix); + fprintf (stderr, "incorrect value\n"); + abort (); + } + + if (strncmp (actual, expected_prefix, strlen (expected_prefix))) + { + fail ("%s: actual: \"%s\" did not begin with expected prefix: \"%s\"", + test, actual, expected_prefix); + fprintf (stderr, "incorrect value\n"); + abort (); + } + + pass ("%s: actual: \"%s\" begins with expected prefix: \"%s\"", + test, actual, expected_prefix); +} + static void set_options (gcc_jit_context *ctxt, const char *argv0) { /* Set up options. */ diff --git a/gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c b/gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c new file mode 100644 index 00000000000..13f5e3b5b83 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c @@ -0,0 +1,38 @@ +/* PR jit/63969: libgccjit would segfault inside gcc_jit_context_compile + if the driver wasn't found on PATH if GCC_JIT_STR_OPTION_PROGNAME was + NULL. */ + +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Create nothing within the context. */ + + /* harness.h's set_options has set a sane value for + GCC_JIT_STR_OPTION_PROGNAME, but PR jit/63969 only segfaulted if it's + NULL. + + Unset it. */ + gcc_jit_context_set_str_option (ctxt, GCC_JIT_STR_OPTION_PROGNAME, NULL); + + /* Break PATH, so that the driver can't be found + by gcc::jit::playback::context::compile () + within gcc_jit_context_compile. */ + unsetenv ("PATH"); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + /* Verify that a sane error message was emitted. */ + CHECK_STRING_STARTS_WITH (gcc_jit_context_get_first_error (ctxt), + "error invoking gcc driver"); +}