Changeset 211828 in webkit
- Timestamp:
- Feb 7, 2017, 12:01:35 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r211818 r211828 1 2017-02-05 Mark Lam <mark.lam@apple.com> 2 3 The SigillCrashAnalyzer should play nicer with client code that may install its own SIGILL handler. 4 https://bugs.webkit.org/show_bug.cgi?id=167858 5 6 Reviewed by Michael Saboff. 7 8 Here are the scenarios that may come up: 9 10 1. Client code did not install a SIGILL handler. 11 - In this case, once we're done analyzing the SIGILL, we can just restore the 12 default handler and return to let the OS do the default action i.e. capture 13 a core dump. 14 15 2. Client code installed a SIGILL handler before JSC does. 16 - In this case, we will see a non-null handler returned as the old signal 17 handler when we install ours. 18 - In our signal handler, after doing our crash analysis, we should invoke the 19 client handler to let it do its work. 20 - Our analyzer can also tell us if the SIGILL source is from JSC code in 21 general (right now, this would just mean JIT code). 22 - If the SIGILL source is not from JSC, we'll just let the client handler 23 decided how to proceed. We assume that the client handler will do the right 24 thing (which is how the old behavior is before the SigillCrashAnalyzer was 25 introduced). 26 - If the SIGILL source is from JSC, then we know the SIGILL is an unrecoverable 27 condition. Hence, after we have given the client handler a chance to run, 28 we should restore the default handler and let the OS capture a core dump. 29 This intentionally overrides whatever signal settings the client handler may 30 have set. 31 32 3. Client code installed a SIGILL handler after JSC does. 33 - In this case, we are dependent on the client handler to call our handler 34 after it does its work. This is compatible with the old behavior before 35 SigillCrashAnalyzer was introduced. 36 - In our signal handler, if we determine that the SIGILL source is from JSC 37 code, then the SIGILL is not recoverable. We should then restore the 38 default handler and get a core dump. 39 - If the SIGILL source is not from JSC, we check to see if there's a client 40 handler installed after us. 41 - If we detect a client handler installed after us, we defer judgement on what 42 to do to the client handler. Since the client handler did not uninstall 43 itself, it must have considered itself to have recovered from the SIGILL. 44 We'll trust the client handler and take no restore action of our own (which 45 is compatible with old code behavior). 46 - If we detect no client handler and we have no previous handler, then we 47 should restore the default handler and get a core dump. 48 49 * tools/SigillCrashAnalyzer.cpp: 50 (JSC::handleCrash): 51 (JSC::installCrashHandler): 52 (JSC::SigillCrashAnalyzer::analyze): Deleted. 53 1 54 2017-02-07 Yusuke Suzuki <utatane.tea@gmail.com> 2 55 -
trunk/Source/JavaScriptCore/tools/SigillCrashAnalyzer.cpp
r211684 r211828 48 48 public: 49 49 static SigillCrashAnalyzer& instance(); 50 void analyze(SignalContext&); 50 51 enum class CrashSource { 52 Unknown, 53 JavaScriptCore, 54 Other, 55 }; 56 CrashSource analyze(SignalContext&); 51 57 52 58 private: … … 166 172 #endif 167 173 168 struct sigaction oldSigIllAction; 169 170 static void handleCrash(int, siginfo_t*, void* uap) 171 { 172 sigaction(SIGILL, &oldSigIllAction, nullptr); 173 174 struct sigaction originalSigIllAction; 175 176 static void handleCrash(int signalNumber, siginfo_t* info, void* uap) 177 { 174 178 SignalContext context(static_cast<ucontext_t*>(uap)->uc_mcontext); 175 179 SigillCrashAnalyzer& analyzer = SigillCrashAnalyzer::instance(); 176 analyzer.analyze(context); 180 auto crashSource = analyzer.analyze(context); 181 182 auto originalAction = originalSigIllAction.sa_sigaction; 183 if (originalAction) { 184 // It is always safe to just invoke the original handler using the sa_sigaction form 185 // without checking for the SA_SIGINFO flag. If the original handler is of the 186 // sa_handler form, it will just ignore the 2nd and 3rd arguments since sa_handler is a 187 // subset of sa_sigaction. This is what the man pages says the OS does anyway. 188 originalAction(signalNumber, info, uap); 189 } 190 191 if (crashSource == SigillCrashAnalyzer::CrashSource::JavaScriptCore) { 192 // Restore the default handler so that we can get a core dump. 193 struct sigaction defaultAction; 194 defaultAction.sa_handler = SIG_DFL; 195 sigfillset(&defaultAction.sa_mask); 196 defaultAction.sa_flags = 0; 197 sigaction(SIGILL, &defaultAction, nullptr); 198 } else if (!originalAction) { 199 // Pre-emptively restore the default handler but we may roll it back below. 200 struct sigaction currentAction; 201 struct sigaction defaultAction; 202 defaultAction.sa_handler = SIG_DFL; 203 sigfillset(&defaultAction.sa_mask); 204 defaultAction.sa_flags = 0; 205 sigaction(SIGILL, &defaultAction, ¤tAction); 206 207 if (currentAction.sa_sigaction != handleCrash) { 208 // This means that there's a client handler installed after us. This also means 209 // that the client handler thinks it was able to recover from the SIGILL, and 210 // did not uninstall itself. We can't argue with this because the crash isn't 211 // known to be from a JavaScriptCore source. Hence, restore the client handler 212 // and keep going. 213 sigaction(SIGILL, ¤tAction, nullptr); 214 } 215 } 177 216 } 178 217 … … 184 223 sigfillset(&action.sa_mask); 185 224 action.sa_flags = SA_SIGINFO; 186 sigaction(SIGILL, &action, &o ldSigIllAction);225 sigaction(SIGILL, &action, &originalSigIllAction); 187 226 #else 188 227 UNUSED_PARAM(handleCrash); … … 228 267 } 229 268 230 void SigillCrashAnalyzer::analyze(SignalContext& context) 231 { 269 auto SigillCrashAnalyzer::analyze(SignalContext& context) -> CrashSource 270 { 271 CrashSource crashSource = CrashSource::Unknown; 232 272 log("BEGIN SIGILL analysis"); 233 273 … … 258 298 if (!isInJITMemory.value()) { 259 299 log("pc %p is NOT in valid JIT executable memory", pc); 300 crashSource = CrashSource::Other; 260 301 return; 261 302 } 262 303 log("pc %p is in valid JIT executable memory", pc); 304 crashSource = CrashSource::JavaScriptCore; 263 305 264 306 #if CPU(ARM64) … … 295 337 296 338 log("END SIGILL analysis"); 339 return crashSource; 297 340 } 298 341
Note:
See TracChangeset
for help on using the changeset viewer.