diff --git a/oioioi/contests/templates/contests/submission.html b/oioioi/contests/templates/contests/submission.html
index 89fd02dfc..c1b98e7b3 100644
--- a/oioioi/contests/templates/contests/submission.html
+++ b/oioioi/contests/templates/contests/submission.html
@@ -31,8 +31,14 @@
{{ header }}
{% for report in reports %}
-
+
{{ report }}
+
+ {% if submission.status == 'SE' %}
+
+ {% trans "Something went wrong on our side when judging your submission... Try again later or contact the administration if this issue persists." %}
+ {% endif %}
+
{% endfor %}
diff --git a/oioioi/programs/controllers.py b/oioioi/programs/controllers.py
index c3f29781b..cb0e207fd 100644
--- a/oioioi/programs/controllers.py
+++ b/oioioi/programs/controllers.py
@@ -732,6 +732,11 @@ def render_report(self, request, report):
all_outs_generated = allow_download_out
groups = []
+ signals_to_explain = set()
+ # Sioworkers doesn't give us exit codes or signals explicitly. Neither does sio2jail.
+ # This detection mechanism is similar to the one sioworkers uses to give a RE verdict:
+ # https://github.com/sio2project/sioworkers/blob/55776ac98613ff2b11bd63397be536029616b9bb/sio/workers/executors.py#L670
+ signal_exit_msg = 'process exited due to signal '
for group_name, tests in itertools.groupby(
test_reports, attrgetter('test_group')
):
@@ -740,6 +745,13 @@ def render_report(self, request, report):
for test in tests_list:
test.generate_status = picontroller._out_generate_status(request, test)
all_outs_generated &= test.generate_status == 'OK'
+ # Extract all error signals from the test report according to the format
+ if test.comment.startswith(signal_exit_msg):
+ try:
+ signal = int(test.comment[len(signal_exit_msg):])
+ signals_to_explain.add(signal)
+ except ValueError:
+ pass
tests_records = [
{'display_type': get_report_display_type(request, test), 'test': test}
@@ -761,6 +773,7 @@ def render_report(self, request, report):
'allow_test_comments': allow_test_comments,
'all_outs_generated': all_outs_generated,
'is_admin': picontroller.is_admin(request, report),
+ 'signals_to_explain': signals_to_explain,
},
)
diff --git a/oioioi/programs/templates/programs/report-comments.html b/oioioi/programs/templates/programs/report-comments.html
index 98652330e..ee956f2e5 100644
--- a/oioioi/programs/templates/programs/report-comments.html
+++ b/oioioi/programs/templates/programs/report-comments.html
@@ -1,6 +1,9 @@
{% load i18n %}
{% load runtimeformat %}
+{% if allow_test_comments and signals_to_explain %}
+ {% include "programs/report-signal-hint.html" %}
+{% endif %}
{% for group in groups %}
{% for record in group.tests %}
diff --git a/oioioi/programs/templates/programs/report-signal-hint.html b/oioioi/programs/templates/programs/report-signal-hint.html
new file mode 100644
index 000000000..42250272a
--- /dev/null
+++ b/oioioi/programs/templates/programs/report-signal-hint.html
@@ -0,0 +1,73 @@
+{% load i18n %}
+
+
+
+
+ {% for signal in signals_to_explain %}
+ {% if signal == 6 %}
+ {% blocktrans %}
+
Most common causes of the SIGABRT signal (signal 6):
+
+ - Out-of-bounds index access for the vector data structure
+ - Array allocation with an invalid size e.g.
int tab[-1];
+ - Bad use of C++ standard library functions, e.g.
sort()
over an invalid range
+ - A failed assertion when using
assert
- commonly used by the C++ Standard Library
+ - Other illegal memory operations.
+
+ {% endblocktrans %}
+ {% elif signal == 7 %}
+ {% blocktrans %}
+
The SIGBUS signal (signal 7) can mean a general memory violation, and can
+ be caused by trying to access an invalid memory address.
+ {% endblocktrans %}
+
+ {% elif signal == 8 %}
+ {% blocktrans %}
+
Most common causes of the SIGFPE signal (signal 8):
+
+ - Overflows/underflows for floating-point numbers
+ - Division by zero, either with floating-point numbers and integers
+ - Other illegal arithmetic operations, e.g. square-root of negative numbers.
+
+ {% endblocktrans %}
+ {% elif signal == 9 %}
+ {% blocktrans %}
+
Most common sources for the SIGKILL signal (signal 9):
+
+ - Your global variable exceeds the memory limit
+
(The difference compared to MLE is that the program exits before it can even "fully start")
+
+ - Other unexpected operations causing the program to get terminated preemptively.
+
+ {% endblocktrans %}
+ {% elif signal == 11 %}
+ {% blocktrans %}
+
Most common causes of the SIGSEGV signal (signal 11):
+
+ - Out-of-bounds array accesses
+ - De-referencing an invalid pointer (an empty "null-pointer" or a pointer to memory which has already been freed)
+ - Other memory violation errors
+
+ {% endblocktrans %}
+ {% elif signal == 31 %}
+ {% blocktrans %}
+
Most common causes of the SIGSYS signal (signal 31):
+
+ - Using a system call (syscall) that's not allowed by this task/contest.
+ - Using an invalid/non-existent system call.
+
+ {% endblocktrans %}
+ {% else %}
+
+ {% blocktranslate with signal=signal %}
+ Signal {{ signal }} shouldn't show up while checking...
+ We recommend reporting this issue.
+ {% endblocktranslate %}
+
+ {% endif %}
+ {% endfor %}
+
+ {% blocktranslate %}
+ Program execution can differ depending on the operating system used and the execution environment.
+ {% endblocktranslate %}
+
diff --git a/oioioi/programs/templates/programs/report.html b/oioioi/programs/templates/programs/report.html
index 0e4e4d9eb..e0e95e1e5 100644
--- a/oioioi/programs/templates/programs/report.html
+++ b/oioioi/programs/templates/programs/report.html
@@ -19,6 +19,14 @@ {% trans "Report:" %} {{ report.kind }}
{{ compilation_report.compiler_output }}
+ {% if 'relocation truncated to fit' in compilation_report.compiler_output %}
+
+
+ {% blocktrans %}
+ This compilation error most commonly occurs when your global variable(s) are too large.
+ {% endblocktrans %}
+
+ {% endif %}
{% else %}
{% include "programs/report-body.html" %}
{% include "programs/report-comments.html" with groups=groups %}