< prev index next >

src/share/vm/utilities/vmError.cpp

Print this page
rev 12508 : 8166944: Hanging Error Reporting steps may lead to torn error logs.
Reviewed-by: cjplummer, dholmes
Summary: Interupt error reporting if reporting steps hang to enable subsequent reporting steps to run.
   1 /*
   2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <fcntl.h>
  26 #include "precompiled.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "compiler/compileBroker.hpp"
  29 #include "compiler/disassembler.hpp"
  30 #include "gc/shared/collectedHeap.hpp"
  31 #include "logging/logConfiguration.hpp"
  32 #include "prims/whitebox.hpp"
  33 #include "runtime/arguments.hpp"
  34 #include "runtime/atomic.hpp"
  35 #include "runtime/frame.inline.hpp"
  36 #include "runtime/init.hpp"
  37 #include "runtime/os.hpp"
  38 #include "runtime/thread.inline.hpp"
  39 #include "runtime/vmThread.hpp"
  40 #include "runtime/vm_operations.hpp"

  41 #include "services/memTracker.hpp"
  42 #include "trace/traceMacros.hpp"
  43 #include "utilities/debug.hpp"
  44 #include "utilities/decoder.hpp"
  45 #include "utilities/defaultStream.hpp"
  46 #include "utilities/errorReporter.hpp"
  47 #include "utilities/events.hpp"
  48 #include "utilities/vmError.hpp"
  49 
  50 // List of environment variables that should be reported in error log file.
  51 const char *env_list[] = {
  52   // All platforms
  53   "JAVA_HOME", "JRE_HOME", "JAVA_TOOL_OPTIONS", "_JAVA_OPTIONS", "CLASSPATH",
  54   "JAVA_COMPILER", "PATH", "USERNAME",
  55 
  56   // Env variables that are defined on Solaris/Linux/BSD
  57   "LD_LIBRARY_PATH", "LD_PRELOAD", "SHELL", "DISPLAY",
  58   "HOSTTYPE", "OSTYPE", "ARCH", "MACHTYPE",
  59 
  60   // defined on Linux


 295 // information that may be unsafe to get after a fatal error. If it happens,
 296 // you may find nested report_and_die() frames when you look at the stack
 297 // in a debugger.
 298 //
 299 // In general, a hang in error handler is much worse than a crash or internal
 300 // error, as it's harder to recover from a hang. Deadlock can happen if we
 301 // try to grab a lock that is already owned by current thread, or if the
 302 // owner is blocked forever (e.g. in os::infinite_sleep()). If possible, the
 303 // error handler and all the functions it called should avoid grabbing any
 304 // lock. An important thing to notice is that memory allocation needs a lock.
 305 //
 306 // We should avoid using large stack allocated buffers. Many errors happen
 307 // when stack space is already low. Making things even worse is that there
 308 // could be nested report_and_die() calls on stack (see above). Only one
 309 // thread can report error, so large buffers are statically allocated in data
 310 // segment.
 311 
 312 int          VMError::_current_step;
 313 const char*  VMError::_current_step_info;
 314 






























 315 void VMError::report(outputStream* st, bool _verbose) {
 316 
 317 # define BEGIN if (_current_step == 0) { _current_step = __LINE__;
 318 # define STEP(s) } if (_current_step < __LINE__) { _current_step = __LINE__; _current_step_info = s;

 319 # define END }
 320 
 321   // don't allocate large buffer on stack
 322   static char buf[O_BUFLEN];
 323 
 324   BEGIN
 325 
 326   STEP("printing fatal error message")
 327 
 328     st->print_cr("#");
 329     if (should_report_bug(_id)) {
 330       st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
 331     } else {
 332       st->print_cr("# There is insufficient memory for the Java "
 333                    "Runtime Environment to continue.");
 334     }
 335 
 336 #ifndef PRODUCT
 337   // Error handler self tests
 338 
 339   // test secondary error handling. Test it twice, to test that resetting
 340   // error handler after a secondary crash works.
 341   STEP("test secondary crash 1")
 342     if (_verbose && TestCrashInErrorHandler != 0) {
 343       st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
 344         TestCrashInErrorHandler);
 345       controlled_crash(TestCrashInErrorHandler);
 346     }
 347 
 348   STEP("test secondary crash 2")
 349     if (_verbose && TestCrashInErrorHandler != 0) {
 350       st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
 351         TestCrashInErrorHandler);
 352       controlled_crash(TestCrashInErrorHandler);
 353     }
 354 












 355   STEP("test safefetch in error handler")
 356     // test whether it is safe to use SafeFetch32 in Crash Handler. Test twice
 357     // to test that resetting the signal handler works correctly.
 358     if (_verbose && TestSafeFetchInErrorHandler) {
 359       st->print_cr("Will test SafeFetch...");
 360       if (CanUseSafeFetch32()) {
 361         int* const invalid_pointer = (int*) get_segfault_address();
 362         const int x = 0x76543210;
 363         int i1 = SafeFetch32(invalid_pointer, x);
 364         int i2 = SafeFetch32(invalid_pointer, x);
 365         if (i1 == x && i2 == x) {
 366           st->print_cr("SafeFetch OK."); // Correctly deflected and returned default pattern
 367         } else {
 368           st->print_cr("??");
 369         }
 370       } else {
 371         st->print_cr("not possible; skipped.");
 372       }
 373     }
 374 #endif // PRODUCT


1159       Atomic::cmpxchg_ptr(mytid, &first_error_tid, -1) == -1) {
1160 
1161     // Initialize time stamps to use the same base.
1162     out.time_stamp().update_to(1);
1163     log.time_stamp().update_to(1);
1164 
1165     _id = id;
1166     _message = message;
1167     _thread = thread;
1168     _pc = pc;
1169     _siginfo = siginfo;
1170     _context = context;
1171     _filename = filename;
1172     _lineno = lineno;
1173     _size = size;
1174     jio_vsnprintf(_detail_msg, sizeof(_detail_msg), detail_fmt, detail_args);
1175 
1176     // first time
1177     set_error_reported();
1178 



1179     if (ShowMessageBoxOnError || PauseAtExit) {
1180       show_message_box(buffer, sizeof(buffer));
1181 
1182       // User has asked JVM to abort. Reset ShowMessageBoxOnError so the
1183       // WatcherThread can kill JVM if the error handler hangs.
1184       ShowMessageBoxOnError = false;
1185     }
1186 
1187     os::check_dump_limit(buffer, sizeof(buffer));
1188 
1189     // reset signal handlers or exception filter; make sure recursive crashes
1190     // are handled properly.
1191     reset_signal_handlers();
1192 
1193     TRACE_VM_ERROR();
1194 
1195   } else {
1196     // If UseOsErrorReporting we call this for each level of the call stack
1197     // while searching for the exception handler.  Only the first level needs
1198     // to be reported.
1199     if (UseOSErrorReporting && log_done) return;
1200 
1201     // This is not the first error, see if it happened in a different thread
1202     // or in the same thread during error reporting.
1203     if (first_error_tid != mytid) {
1204       char msgbuf[64];
1205       jio_snprintf(msgbuf, sizeof(msgbuf),
1206                    "[thread " INTX_FORMAT " also had an error]",
1207                    mytid);
1208       out.print_raw_cr(msgbuf);
1209 
1210       // error reporting is not MT-safe, block current thread
1211       os::infinite_sleep();
1212 
1213     } else {
1214       if (recursive_error_count++ > 30) {
1215         out.print_raw_cr("[Too many errors, abort]");
1216         os::die();
1217       }
1218 




















1219       jio_snprintf(buffer, sizeof(buffer),
1220                    "[error occurred during error reporting (%s), id 0x%x]",
1221                    _current_step_info, _id);
1222       if (log.is_open()) {
1223         log.cr();
1224         log.print_raw_cr(buffer);
1225         log.cr();
1226       } else {
1227         out.cr();
1228         out.print_raw_cr(buffer);
1229         out.cr();
1230       }
1231     }
1232   }
1233 
1234   // print to screen
1235   if (!out_done) {
1236     report(&out, false);
1237 
1238     out_done = true;
1239 
1240     _current_step = 0;
1241     _current_step_info = "";
1242   }
1243 
1244   // print to error log file
1245   if (!log_done) {
1246     // see if log file is already open
1247     if (!log.is_open()) {
1248       // open log file
1249       int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));


1404                      os::strerror(errno), os::errno_name(errno), errno);
1405     }
1406   }
1407 }
1408 
1409 void VMError::report_java_out_of_memory(const char* message) {
1410   if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
1411     MutexLocker ml(Heap_lock);
1412     VM_ReportJavaOutOfMemory op(message);
1413     VMThread::execute(&op);
1414   }
1415 }
1416 
1417 void VMError::show_message_box(char *buf, int buflen) {
1418   bool yes;
1419   do {
1420     error_string(buf, buflen);
1421     yes = os::start_debugging(buf,buflen);
1422   } while (yes);
1423 }















































   1 /*
   2  * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <fcntl.h>
  26 #include "precompiled.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "compiler/compileBroker.hpp"
  29 #include "compiler/disassembler.hpp"
  30 #include "gc/shared/collectedHeap.hpp"
  31 #include "logging/logConfiguration.hpp"
  32 #include "prims/whitebox.hpp"
  33 #include "runtime/arguments.hpp"
  34 #include "runtime/atomic.hpp"
  35 #include "runtime/frame.inline.hpp"
  36 #include "runtime/init.hpp"
  37 #include "runtime/os.hpp"
  38 #include "runtime/thread.inline.hpp"
  39 #include "runtime/vmThread.hpp"
  40 #include "runtime/vm_operations.hpp"
  41 #include "runtime/vm_version.hpp"
  42 #include "services/memTracker.hpp"
  43 #include "trace/traceMacros.hpp"
  44 #include "utilities/debug.hpp"
  45 #include "utilities/decoder.hpp"
  46 #include "utilities/defaultStream.hpp"
  47 #include "utilities/errorReporter.hpp"
  48 #include "utilities/events.hpp"
  49 #include "utilities/vmError.hpp"
  50 
  51 // List of environment variables that should be reported in error log file.
  52 const char *env_list[] = {
  53   // All platforms
  54   "JAVA_HOME", "JRE_HOME", "JAVA_TOOL_OPTIONS", "_JAVA_OPTIONS", "CLASSPATH",
  55   "JAVA_COMPILER", "PATH", "USERNAME",
  56 
  57   // Env variables that are defined on Solaris/Linux/BSD
  58   "LD_LIBRARY_PATH", "LD_PRELOAD", "SHELL", "DISPLAY",
  59   "HOSTTYPE", "OSTYPE", "ARCH", "MACHTYPE",
  60 
  61   // defined on Linux


 296 // information that may be unsafe to get after a fatal error. If it happens,
 297 // you may find nested report_and_die() frames when you look at the stack
 298 // in a debugger.
 299 //
 300 // In general, a hang in error handler is much worse than a crash or internal
 301 // error, as it's harder to recover from a hang. Deadlock can happen if we
 302 // try to grab a lock that is already owned by current thread, or if the
 303 // owner is blocked forever (e.g. in os::infinite_sleep()). If possible, the
 304 // error handler and all the functions it called should avoid grabbing any
 305 // lock. An important thing to notice is that memory allocation needs a lock.
 306 //
 307 // We should avoid using large stack allocated buffers. Many errors happen
 308 // when stack space is already low. Making things even worse is that there
 309 // could be nested report_and_die() calls on stack (see above). Only one
 310 // thread can report error, so large buffers are statically allocated in data
 311 // segment.
 312 
 313 int          VMError::_current_step;
 314 const char*  VMError::_current_step_info;
 315 
 316 volatile jlong VMError::_reporting_start_time = -1;
 317 volatile bool VMError::_reporting_did_timeout = false;
 318 volatile jlong VMError::_step_start_time = -1;
 319 volatile bool VMError::_step_did_timeout = false;
 320 
 321 // Helper, return current timestamp for timeout handling.
 322 jlong VMError::get_current_timestamp() {
 323   return os::javaTimeNanos();
 324 }
 325 // Factor to translate the timestamp to seconds.
 326 #define TIMESTAMP_TO_SECONDS_FACTOR (1000 * 1000 * 1000)
 327 
 328 void VMError::record_reporting_start_time() {
 329   const jlong now = get_current_timestamp();
 330   Atomic::store(now, &_reporting_start_time);
 331 }
 332 
 333 jlong VMError::get_reporting_start_time() {
 334   return Atomic::load(&_reporting_start_time);
 335 }
 336 
 337 void VMError::record_step_start_time() {
 338   const jlong now = get_current_timestamp();
 339   Atomic::store(now, &_step_start_time);
 340 }
 341 
 342 jlong VMError::get_step_start_time() {
 343   return Atomic::load(&_step_start_time);
 344 }
 345 
 346 void VMError::report(outputStream* st, bool _verbose) {
 347 
 348 # define BEGIN if (_current_step == 0) { _current_step = __LINE__;
 349 # define STEP(s) } if (_current_step < __LINE__) { _current_step = __LINE__; _current_step_info = s; \
 350   record_step_start_time(); _step_did_timeout = false;
 351 # define END }
 352 
 353   // don't allocate large buffer on stack
 354   static char buf[O_BUFLEN];
 355 
 356   BEGIN
 357 
 358   STEP("printing fatal error message")
 359 
 360     st->print_cr("#");
 361     if (should_report_bug(_id)) {
 362       st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
 363     } else {
 364       st->print_cr("# There is insufficient memory for the Java "
 365                    "Runtime Environment to continue.");
 366     }
 367 
 368 #ifndef PRODUCT
 369   // Error handler self tests
 370 
 371   // test secondary error handling. Test it twice, to test that resetting
 372   // error handler after a secondary crash works.
 373   STEP("test secondary crash 1")
 374     if (_verbose && TestCrashInErrorHandler != 0) {
 375       st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
 376         TestCrashInErrorHandler);
 377       controlled_crash(TestCrashInErrorHandler);
 378     }
 379 
 380   STEP("test secondary crash 2")
 381     if (_verbose && TestCrashInErrorHandler != 0) {
 382       st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
 383         TestCrashInErrorHandler);
 384       controlled_crash(TestCrashInErrorHandler);
 385     }
 386 
 387   // TestUnresponsiveErrorHandler: We want to test both step timeouts and global timeout.
 388   // Step to global timeout ratio is 4:1, so in order to be absolutely sure we hit the
 389   // global timeout, let's execute the timeout step five times.
 390   // See corresponding test in test/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java
 391   #define TIMEOUT_TEST_STEP STEP("test unresponsive error reporting step") \
 392     if (_verbose && TestUnresponsiveErrorHandler) { os::infinite_sleep(); }
 393   TIMEOUT_TEST_STEP
 394   TIMEOUT_TEST_STEP
 395   TIMEOUT_TEST_STEP
 396   TIMEOUT_TEST_STEP
 397   TIMEOUT_TEST_STEP
 398 
 399   STEP("test safefetch in error handler")
 400     // test whether it is safe to use SafeFetch32 in Crash Handler. Test twice
 401     // to test that resetting the signal handler works correctly.
 402     if (_verbose && TestSafeFetchInErrorHandler) {
 403       st->print_cr("Will test SafeFetch...");
 404       if (CanUseSafeFetch32()) {
 405         int* const invalid_pointer = (int*) get_segfault_address();
 406         const int x = 0x76543210;
 407         int i1 = SafeFetch32(invalid_pointer, x);
 408         int i2 = SafeFetch32(invalid_pointer, x);
 409         if (i1 == x && i2 == x) {
 410           st->print_cr("SafeFetch OK."); // Correctly deflected and returned default pattern
 411         } else {
 412           st->print_cr("??");
 413         }
 414       } else {
 415         st->print_cr("not possible; skipped.");
 416       }
 417     }
 418 #endif // PRODUCT


1203       Atomic::cmpxchg_ptr(mytid, &first_error_tid, -1) == -1) {
1204 
1205     // Initialize time stamps to use the same base.
1206     out.time_stamp().update_to(1);
1207     log.time_stamp().update_to(1);
1208 
1209     _id = id;
1210     _message = message;
1211     _thread = thread;
1212     _pc = pc;
1213     _siginfo = siginfo;
1214     _context = context;
1215     _filename = filename;
1216     _lineno = lineno;
1217     _size = size;
1218     jio_vsnprintf(_detail_msg, sizeof(_detail_msg), detail_fmt, detail_args);
1219 
1220     // first time
1221     set_error_reported();
1222 
1223     reporting_started();
1224     record_reporting_start_time();
1225 
1226     if (ShowMessageBoxOnError || PauseAtExit) {
1227       show_message_box(buffer, sizeof(buffer));
1228 
1229       // User has asked JVM to abort. Reset ShowMessageBoxOnError so the
1230       // WatcherThread can kill JVM if the error handler hangs.
1231       ShowMessageBoxOnError = false;
1232     }
1233 
1234     os::check_dump_limit(buffer, sizeof(buffer));
1235 
1236     // reset signal handlers or exception filter; make sure recursive crashes
1237     // are handled properly.
1238     reset_signal_handlers();
1239 
1240     TRACE_VM_ERROR();
1241 
1242   } else {
1243     // If UseOsErrorReporting we call this for each level of the call stack
1244     // while searching for the exception handler.  Only the first level needs
1245     // to be reported.
1246     if (UseOSErrorReporting && log_done) return;
1247 
1248     // This is not the first error, see if it happened in a different thread
1249     // or in the same thread during error reporting.
1250     if (first_error_tid != mytid) {
1251       char msgbuf[64];
1252       jio_snprintf(msgbuf, sizeof(msgbuf),
1253                    "[thread " INTX_FORMAT " also had an error]",
1254                    mytid);
1255       out.print_raw_cr(msgbuf);
1256 
1257       // error reporting is not MT-safe, block current thread
1258       os::infinite_sleep();
1259 
1260     } else {
1261       if (recursive_error_count++ > 30) {
1262         out.print_raw_cr("[Too many errors, abort]");
1263         os::die();
1264       }
1265 
1266       outputStream* const st = log.is_open() ? &log : &out;
1267       st->cr();
1268 
1269       // Timeout handling.
1270       if (_step_did_timeout) {
1271         // The current step had a timeout. Lets continue reporting with the next step.
1272         st->print_raw("[timeout occurred during error reporting in step \"");
1273         st->print_raw(_current_step_info);
1274         st->print_cr("\"] after " INT64_FORMAT " s.",
1275           (get_current_timestamp() - _step_start_time) / TIMESTAMP_TO_SECONDS_FACTOR);
1276       } else if (_reporting_did_timeout) {
1277         // We hit ErrorLogTimeout. Reporting will stop altogether. Let's wrap things
1278         // up, the process is about to be stopped by the WatcherThread.
1279         st->print_cr("------ Timeout during error reporting after " INT64_FORMAT " s. ------",
1280           (get_current_timestamp() - _reporting_start_time) / TIMESTAMP_TO_SECONDS_FACTOR);
1281         st->flush();
1282         // Watcherthread is about to call os::die. Lets just wait.
1283         os::infinite_sleep();
1284       } else {
1285         // Crash or assert during error reporting. Lets continue reporting with the next step.
1286         jio_snprintf(buffer, sizeof(buffer),
1287            "[error occurred during error reporting (%s), id 0x%x]",
1288                    _current_step_info, _id);
1289         st->print_raw_cr(buffer);
1290         st->cr();






1291       }
1292     }
1293   }
1294 
1295   // print to screen
1296   if (!out_done) {
1297     report(&out, false);
1298 
1299     out_done = true;
1300 
1301     _current_step = 0;
1302     _current_step_info = "";
1303   }
1304 
1305   // print to error log file
1306   if (!log_done) {
1307     // see if log file is already open
1308     if (!log.is_open()) {
1309       // open log file
1310       int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));


1465                      os::strerror(errno), os::errno_name(errno), errno);
1466     }
1467   }
1468 }
1469 
1470 void VMError::report_java_out_of_memory(const char* message) {
1471   if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
1472     MutexLocker ml(Heap_lock);
1473     VM_ReportJavaOutOfMemory op(message);
1474     VMThread::execute(&op);
1475   }
1476 }
1477 
1478 void VMError::show_message_box(char *buf, int buflen) {
1479   bool yes;
1480   do {
1481     error_string(buf, buflen);
1482     yes = os::start_debugging(buf,buflen);
1483   } while (yes);
1484 }
1485 
1486 // Timeout handling: check if a timeout happened (either a single step did
1487 // timeout or the whole of error reporting hit ErrorLogTimeout). Interrupt
1488 // the reporting thread if that is the case.
1489 bool VMError::check_timeout() {
1490 
1491   if (ErrorLogTimeout == 0) {
1492     return false;
1493   }
1494 
1495   // Do not check for timeouts if we still have a message box to show to the
1496   // user or if there are OnError handlers to be run.
1497   if (ShowMessageBoxOnError
1498       || (OnError != NULL && OnError[0] != '\0')
1499       || Arguments::abort_hook() != NULL) {
1500     return false;
1501   }
1502 
1503   const jlong reporting_start_time_l = get_reporting_start_time();
1504   const jlong now = get_current_timestamp();
1505   // Timestamp is stored in nanos.
1506   if (reporting_start_time_l > 0) {
1507     const jlong end = reporting_start_time_l + (jlong)ErrorLogTimeout * TIMESTAMP_TO_SECONDS_FACTOR;
1508     if (end <= now) {
1509       _reporting_did_timeout = true;
1510       interrupt_reporting_thread();
1511       return true; // global timeout
1512     }
1513   }
1514 
1515   const jlong step_start_time_l = get_step_start_time();
1516   if (step_start_time_l > 0) {
1517     // A step times out after a quarter of the total timeout. Steps are mostly fast unless they
1518     // hang for some reason, so this simple rule allows for three hanging step and still
1519     // hopefully leaves time enough for the rest of the steps to finish.
1520     const jlong end = step_start_time_l + (jlong)ErrorLogTimeout * TIMESTAMP_TO_SECONDS_FACTOR / 4;
1521     if (end <= now) {
1522       _step_did_timeout = true;
1523       interrupt_reporting_thread();
1524       return false; // (Not a global timeout)
1525     }
1526   }
1527 
1528   return false;
1529 
1530 }
1531 
< prev index next >