jdk

Форк
0
/
threadCrashProtection_posix.cpp 
83 строки · 2.9 Кб
1
/*
2
 * Copyright (c) 2017, 2023, 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 "precompiled.hpp"
26
#include "runtime/thread.hpp"
27
#include "runtime/threadCrashProtection.hpp"
28

29
Thread* ThreadCrashProtection::_protected_thread = nullptr;
30
ThreadCrashProtection* ThreadCrashProtection::_crash_protection = nullptr;
31

32
ThreadCrashProtection::ThreadCrashProtection() {
33
  _protected_thread = Thread::current();
34
  assert(_protected_thread->is_JfrSampler_thread(), "should be JFRSampler");
35
}
36

37
/*
38
 * See the caveats for this class in threadCrashProtection_posix.hpp
39
 * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
40
 * method and returns false. If none of the signals are raised, returns true.
41
 * The callback is supposed to provide the method that should be protected.
42
 */
43
bool ThreadCrashProtection::call(CrashProtectionCallback& cb) {
44
  sigset_t saved_sig_mask;
45

46
  // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask
47
  // since on at least some systems (OS X) siglongjmp will restore the mask
48
  // for the process, not the thread
49
  pthread_sigmask(0, nullptr, &saved_sig_mask);
50
  if (sigsetjmp(_jmpbuf, 0) == 0) {
51
    // make sure we can see in the signal handler that we have crash protection
52
    // installed
53
    _crash_protection = this;
54
    cb.call();
55
    // and clear the crash protection
56
    _crash_protection = nullptr;
57
    _protected_thread = nullptr;
58
    return true;
59
  }
60
  // this happens when we siglongjmp() back
61
  pthread_sigmask(SIG_SETMASK, &saved_sig_mask, nullptr);
62
  _crash_protection = nullptr;
63
  _protected_thread = nullptr;
64
  return false;
65
}
66

67
void ThreadCrashProtection::restore() {
68
  assert(_crash_protection != nullptr, "must have crash protection");
69
  siglongjmp(_jmpbuf, 1);
70
}
71

72
void ThreadCrashProtection::check_crash_protection(int sig,
73
    Thread* thread) {
74

75
  if (thread != nullptr &&
76
      thread == _protected_thread &&
77
      _crash_protection != nullptr) {
78

79
    if (sig == SIGSEGV || sig == SIGBUS) {
80
      _crash_protection->restore();
81
    }
82
  }
83
}
84

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.