aeexception.c revision 1.1.1.1
1/****************************************************************************** 2 * 3 * Module Name: aeexception - Exception and signal handlers 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2017, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#include "aecommon.h" 45 46#define _COMPONENT ACPI_TOOLS 47 ACPI_MODULE_NAME ("aeexception") 48 49 50/* Local prototypes */ 51 52static void 53AeDisplayMethodCallStack ( 54 void); 55 56 57/****************************************************************************** 58 * 59 * FUNCTION: AeExceptionHandler 60 * 61 * PARAMETERS: Standard exception handler parameters 62 * 63 * RETURN: Status 64 * 65 * DESCRIPTION: System exception handler for AcpiExec utility. Called from 66 * the core ACPICA code after any exception during method 67 * execution. 68 * 69 *****************************************************************************/ 70 71ACPI_STATUS 72AeExceptionHandler ( 73 ACPI_STATUS AmlStatus, 74 ACPI_NAME Name, 75 UINT16 Opcode, 76 UINT32 AmlOffset, 77 void *Context) 78{ 79 ACPI_STATUS NewAmlStatus = AmlStatus; 80 ACPI_STATUS Status; 81 ACPI_BUFFER ReturnObj; 82 ACPI_OBJECT_LIST ArgList; 83 ACPI_OBJECT Arg[3]; 84 const char *Exception; 85 ACPI_HANDLE ErrHandle; 86 87 88 Exception = AcpiFormatException (AmlStatus); 89 AcpiOsPrintf (AE_PREFIX 90 "Exception %s during execution\n", Exception); 91 if (Name) 92 { 93 AcpiOsPrintf (AE_PREFIX 94 "Evaluating Method or Node: [%4.4s]", 95 (char *) &Name); 96 } 97 98 AcpiOsPrintf ("\n" AE_PREFIX 99 "AML Opcode [%s], Method Offset ~%5.5X\n", 100 AcpiPsGetOpcodeName (Opcode), AmlOffset); 101 102 /* Invoke the _ERR method if present */ 103 104 Status = AcpiGetHandle (NULL, "\\_ERR", &ErrHandle); 105 if (ACPI_FAILURE (Status)) 106 { 107 goto Cleanup; 108 } 109 110 /* Setup parameter object */ 111 112 ArgList.Count = 3; 113 ArgList.Pointer = Arg; 114 115 Arg[0].Type = ACPI_TYPE_INTEGER; 116 Arg[0].Integer.Value = AmlStatus; 117 118 Arg[1].Type = ACPI_TYPE_STRING; 119 Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception); 120 Arg[1].String.Length = strlen (Exception); 121 122 Arg[2].Type = ACPI_TYPE_INTEGER; 123 Arg[2].Integer.Value = AcpiOsGetThreadId(); 124 125 /* Setup return buffer */ 126 127 ReturnObj.Pointer = NULL; 128 ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 129 130 Status = AcpiEvaluateObject (ErrHandle, NULL, &ArgList, &ReturnObj); 131 if (ACPI_SUCCESS (Status)) 132 { 133 if (ReturnObj.Pointer) 134 { 135 /* Override original status */ 136 137 NewAmlStatus = (ACPI_STATUS) 138 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value; 139 140 /* Free a buffer created via ACPI_ALLOCATE_BUFFER */ 141 142 AcpiOsFree (ReturnObj.Pointer); 143 } 144 } 145 else if (Status != AE_NOT_FOUND) 146 { 147 AcpiOsPrintf (AE_PREFIX 148 "Could not execute _ERR method, %s\n", 149 AcpiFormatException (Status)); 150 } 151 152Cleanup: 153 154 if (AcpiGbl_IgnoreErrors) 155 { 156 /* Global option to ignore all method errors, just return OK */ 157 158 NewAmlStatus = AE_OK; 159 } 160 if (NewAmlStatus != AmlStatus) 161 { 162 /* Request to override actual status with a different status */ 163 164 AcpiOsPrintf (AE_PREFIX 165 "Exception override, new status %s\n\n", 166 AcpiFormatException (NewAmlStatus)); 167 } 168 169 return (NewAmlStatus); 170} 171 172 173/****************************************************************************** 174 * 175 * FUNCTION: AeSignalHandler 176 * 177 * PARAMETERS: Sig 178 * 179 * RETURN: none 180 * 181 * DESCRIPTION: Master signal handler. Currently handles SIGINT (ctrl-c), 182 * and SIGSEGV (Segment violation). 183 * 184 *****************************************************************************/ 185 186void ACPI_SYSTEM_XFACE 187AeSignalHandler ( 188 int Sig) 189{ 190 191 fflush(stdout); 192 AcpiOsPrintf ("\n" AE_PREFIX); 193 194 switch (Sig) 195 { 196 case SIGINT: 197 signal(Sig, SIG_IGN); 198 AcpiOsPrintf ("<Control-C>\n"); 199 200 /* Abort the application if there are no methods executing */ 201 202 if (!AcpiGbl_MethodExecuting) 203 { 204 break; 205 } 206 207 /* 208 * Abort the method(s). This will also dump the method call 209 * stack so there is no need to do it here. The application 210 * will then drop back into the debugger interface. 211 */ 212 AcpiGbl_AbortMethod = TRUE; 213 AcpiOsPrintf (AE_PREFIX "Control Method Call Stack:\n"); 214 signal (SIGINT, AeSignalHandler); 215 return; 216 217 case SIGSEGV: 218 AcpiOsPrintf ("Segmentation Fault\n"); 219 AeDisplayMethodCallStack (); 220 break; 221 222 default: 223 AcpiOsPrintf ("Unknown Signal, %X\n", Sig); 224 break; 225 } 226 227 /* Terminate application -- cleanup then exit */ 228 229 AcpiOsPrintf (AE_PREFIX "Terminating\n"); 230 (void) AcpiOsTerminate (); 231 exit (0); 232} 233 234 235/****************************************************************************** 236 * 237 * FUNCTION: AeDisplayMethodCallStack 238 * 239 * PARAMETERS: None 240 * 241 * RETURN: None 242 * 243 * DESCRIPTION: Display current method call stack, if possible. 244 * 245 * NOTE: Currently only called from a SIGSEGV, so AcpiExec is about 246 * to terminate. 247 * 248 *****************************************************************************/ 249 250static void 251AeDisplayMethodCallStack ( 252 void) 253{ 254 ACPI_WALK_STATE *WalkState; 255 ACPI_THREAD_STATE *ThreadList = AcpiGbl_CurrentWalkList; 256 char *FullPathname = NULL; 257 258 259 if (!AcpiGbl_MethodExecuting) 260 { 261 AcpiOsPrintf (AE_PREFIX "No method is executing\n"); 262 return; 263 } 264 265 /* 266 * Try to find the currently executing control method(s) 267 * 268 * Note: The following code may fault if the data structures are 269 * in an indeterminate state when the interrupt occurs. However, 270 * in practice, this works quite well and can provide very 271 * valuable information. 272 * 273 * 1) Walk the global thread list 274 */ 275 while (ThreadList && 276 (ThreadList->DescriptorType == ACPI_DESC_TYPE_STATE_THREAD)) 277 { 278 /* 2) Walk the walk state list for this thread */ 279 280 WalkState = ThreadList->WalkStateList; 281 while (WalkState && 282 (WalkState->DescriptorType == ACPI_DESC_TYPE_WALK)) 283 { 284 /* An executing control method */ 285 286 if (WalkState->MethodNode) 287 { 288 FullPathname = AcpiNsGetExternalPathname ( 289 WalkState->MethodNode); 290 291 AcpiOsPrintf (AE_PREFIX 292 "Executing Method: %s\n", FullPathname); 293 } 294 295 /* Execution of a deferred opcode/node */ 296 297 if (WalkState->DeferredNode) 298 { 299 FullPathname = AcpiNsGetExternalPathname ( 300 WalkState->DeferredNode); 301 302 AcpiOsPrintf (AE_PREFIX 303 "Evaluating deferred node: %s\n", FullPathname); 304 } 305 306 /* Get the currently executing AML opcode */ 307 308 if ((WalkState->Opcode != AML_INT_METHODCALL_OP) && 309 FullPathname) 310 { 311 AcpiOsPrintf (AE_PREFIX 312 "Current AML Opcode in %s: [%s]-0x%4.4X at %p\n", 313 FullPathname, AcpiPsGetOpcodeName (WalkState->Opcode), 314 WalkState->Opcode, WalkState->Aml); 315 } 316 317 if (FullPathname) 318 { 319 ACPI_FREE (FullPathname); 320 FullPathname = NULL; 321 } 322 323 WalkState = WalkState->Next; 324 } 325 326 ThreadList = ThreadList->Next; 327 } 328} 329