Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

insert backtrace printing into user-facing JL_CATCH #38201

Merged
merged 1 commit into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -2072,11 +2072,12 @@ static void jl_reinit_item(jl_value_t *v, int how, arraylist_t *tracee_list)
}
}
JL_CATCH {
jl_printf(JL_STDERR, "WARNING: error while reinitializing value ");
jl_static_show(JL_STDERR, v);
jl_printf(JL_STDERR, ":\n");
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf(JL_STDERR, "\n");
jl_printf((JL_STREAM*)STDERR_FILENO, "WARNING: error while reinitializing value ");
jl_static_show((JL_STREAM*)STDERR_FILENO, v);
jl_printf((JL_STREAM*)STDERR_FILENO, ":\n");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,10 @@ static void run_finalizer(jl_ptls_t ptls, jl_value_t *o, jl_value_t *ff)
jl_get_ptls_states()->world_age = last_age;
}
JL_CATCH {
jl_printf(JL_STDERR, "error in running finalizer: ");
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf(JL_STDERR, "\n");
jl_printf((JL_STREAM*)STDERR_FILENO, "error in running finalizer: ");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // writen to STDERR_FILENO
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ void jl_call_tracer(tracer_cb callback, jl_value_t *tracee)
}
JL_CATCH {
ptls->in_pure_callback = last_in;
jl_printf(JL_STDERR, "WARNING: tracer callback function threw an error:\n");
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf(JL_STDERR, "\n");
jlbacktrace();
jl_printf((JL_STREAM*)STDERR_FILENO, "WARNING: tracer callback function threw an error:\n");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
}
}

Expand Down Expand Up @@ -300,9 +300,9 @@ jl_code_info_t *jl_type_infer(jl_method_instance_t *mi, size_t world, int force)
src = (jl_code_info_t*)jl_apply(fargs, 3);
}
JL_CATCH {
jl_printf(JL_STDERR, "Internal error: encountered unexpected error in runtime:\n");
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf(JL_STDERR, "\n");
jl_printf((JL_STREAM*)STDERR_FILENO, "Internal error: encountered unexpected error in runtime:\n");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
src = NULL;
}
Expand Down
12 changes: 8 additions & 4 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,10 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode)
ptls->world_age = last_age;
}
JL_CATCH {
jl_printf(JL_STDERR, "\natexit hook threw an error: ");
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\natexit hook threw an error: ");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
}
}
}
Expand Down Expand Up @@ -258,8 +260,10 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode)
//error handling -- continue cleanup, as much as possible
assert(item);
uv_unref(item->h);
jl_printf(JL_STDERR, "error during exit cleanup: close: ");
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "error during exit cleanup: close: ");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
item = next_shutdown_queue_item(item);
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/jlapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,9 @@ static int exec_program(char *program)
jl_load(jl_main_module, program);
}
JL_CATCH {
// TODO: It is possible for this output
// to be mangled due to `jlbacktrace`
// printing directly to STDERR_FILENO.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to resolve this as you've done elsewhere then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't immediately clear to me how to do so. The code mixes JL_STDERR and jl_stderr_objs and I presume it does so for a reason. I am not sure if it is gurantueed that hose two streams will be the same.

Some git archeology shows that this is code from the ancient times.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes I see. So it seems that errs could certainly be pointing to some other stream if redirect_stderr was called. I think the fix here, in principle, is to have some shim to call display_error() rather than printing the current exception and backtrace separately. If display_error doesn't exist or fails, then the fallback path of shown_err == 0 would be taken.

jl_value_t *errs = jl_stderr_obj();
JL_GC_PUSH1(&errs);
volatile int shown_err = 0;
Expand All @@ -510,11 +513,11 @@ static int exec_program(char *program)
}
JL_GC_POP();
if (!shown_err) {
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf(JL_STDERR, "\n");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
}
jlbacktrace();
jl_printf(JL_STDERR, "\n");
jlbacktrace(); // written to STDERR_FILENO
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
return 1;
}
return 0;
Expand Down Expand Up @@ -597,10 +600,10 @@ static NOINLINE int true_main(int argc, char *argv[])
free(line);
line = NULL;
}
jl_printf(JL_STDERR, "\nparser error:\n");
jl_static_show(JL_STDERR, jl_current_exception());
jl_printf(JL_STDERR, "\n");
jlbacktrace();
jl_printf((JL_STREAM*)STDERR_FILENO, "\nparser error:\n");
jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception());
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
}
}
return 0;
Expand Down
8 changes: 4 additions & 4 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,10 +558,10 @@ JL_DLLEXPORT void jl_switchto(jl_task_t **pt)

JL_DLLEXPORT JL_NORETURN void jl_no_exc_handler(jl_value_t *e)
{
jl_printf(JL_STDERR, "fatal: error thrown and no exception handler available.\n");
jl_static_show(JL_STDERR, e);
jl_printf(JL_STDERR, "\n");
jlbacktrace();
jl_printf((JL_STREAM*)STDERR_FILENO, "fatal: error thrown and no exception handler available.\n");
jl_static_show((JL_STREAM*)STDERR_FILENO, e);
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
jl_exit(1);
}

Expand Down
8 changes: 3 additions & 5 deletions test/channels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,9 @@ end
@test istaskdone(t)
@test fetch(t)
@test run[] == 3
@test fetch(errstream) == """
error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer")
error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer")
error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer")
"""
output = fetch(errstream)
@test 3 == length(findall(
"""error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer")""", output))
# test for invalid state in Workqueue during yield
t = @async nothing
t._state = 66
Expand Down