1 /****************************************************************************** 2 * 3 * Module Name: dsdebug - Parser/Interpreter interface - debugging 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 "acpi.h" 45 #include "accommon.h" 46 #include "acdispat.h" 47 #include "acnamesp.h" 48 #include "acdisasm.h" 49 #include "acinterp.h" 50 51 52 #define _COMPONENT ACPI_DISPATCHER 53 ACPI_MODULE_NAME ("dsdebug") 54 55 56 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) 57 58 /* Local prototypes */ 59 60 static void 61 AcpiDsPrintNodePathname ( 62 ACPI_NAMESPACE_NODE *Node, 63 const char *Message); 64 65 66 /******************************************************************************* 67 * 68 * FUNCTION: AcpiDsPrintNodePathname 69 * 70 * PARAMETERS: Node - Object 71 * Message - Prefix message 72 * 73 * DESCRIPTION: Print an object's full namespace pathname 74 * Manages allocation/freeing of a pathname buffer 75 * 76 ******************************************************************************/ 77 78 static void 79 AcpiDsPrintNodePathname ( 80 ACPI_NAMESPACE_NODE *Node, 81 const char *Message) 82 { 83 ACPI_BUFFER Buffer; 84 ACPI_STATUS Status; 85 86 87 ACPI_FUNCTION_TRACE (DsPrintNodePathname); 88 89 if (!Node) 90 { 91 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[NULL NAME]")); 92 return_VOID; 93 } 94 95 /* Convert handle to full pathname and print it (with supplied message) */ 96 97 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 98 99 Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE); 100 if (ACPI_SUCCESS (Status)) 101 { 102 if (Message) 103 { 104 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "%s ", Message)); 105 } 106 107 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[%s] (Node %p)", 108 (char *) Buffer.Pointer, Node)); 109 ACPI_FREE (Buffer.Pointer); 110 } 111 112 return_VOID; 113 } 114 115 116 /******************************************************************************* 117 * 118 * FUNCTION: AcpiDsDumpMethodStack 119 * 120 * PARAMETERS: Status - Method execution status 121 * WalkState - Current state of the parse tree walk 122 * Op - Executing parse op 123 * 124 * RETURN: None 125 * 126 * DESCRIPTION: Called when a method has been aborted because of an error. 127 * Dumps the method execution stack. 128 * 129 ******************************************************************************/ 130 131 void 132 AcpiDsDumpMethodStack ( 133 ACPI_STATUS Status, 134 ACPI_WALK_STATE *WalkState, 135 ACPI_PARSE_OBJECT *Op) 136 { 137 ACPI_PARSE_OBJECT *Next; 138 ACPI_THREAD_STATE *Thread; 139 ACPI_WALK_STATE *NextWalkState; 140 ACPI_NAMESPACE_NODE *PreviousMethod = NULL; 141 ACPI_OPERAND_OBJECT *MethodDesc; 142 143 144 ACPI_FUNCTION_TRACE (DsDumpMethodStack); 145 146 /* Ignore control codes, they are not errors */ 147 148 if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) 149 { 150 return_VOID; 151 } 152 153 /* We may be executing a deferred opcode */ 154 155 if (WalkState->DeferredNode) 156 { 157 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 158 "Executing subtree for Buffer/Package/Region\n")); 159 return_VOID; 160 } 161 162 /* 163 * If there is no Thread, we are not actually executing a method. 164 * This can happen when the iASL compiler calls the interpreter 165 * to perform constant folding. 166 */ 167 Thread = WalkState->Thread; 168 if (!Thread) 169 { 170 return_VOID; 171 } 172 173 /* Display exception and method name */ 174 175 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 176 "\n**** Exception %s during execution of method ", 177 AcpiFormatException (Status))); 178 179 AcpiDsPrintNodePathname (WalkState->MethodNode, NULL); 180 181 /* Display stack of executing methods */ 182 183 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, 184 "\n\nMethod Execution Stack:\n")); 185 NextWalkState = Thread->WalkStateList; 186 187 /* Walk list of linked walk states */ 188 189 while (NextWalkState) 190 { 191 MethodDesc = NextWalkState->MethodDesc; 192 if (MethodDesc) 193 { 194 AcpiExStopTraceMethod ( 195 (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node, 196 MethodDesc, WalkState); 197 } 198 199 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 200 " Method [%4.4s] executing: ", 201 AcpiUtGetNodeName (NextWalkState->MethodNode))); 202 203 /* First method is the currently executing method */ 204 205 if (NextWalkState == WalkState) 206 { 207 if (Op) 208 { 209 /* Display currently executing ASL statement */ 210 211 Next = Op->Common.Next; 212 Op->Common.Next = NULL; 213 214 #ifdef ACPI_DISASSEMBLER 215 AcpiOsPrintf ("Failed at "); 216 AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX); 217 #endif 218 Op->Common.Next = Next; 219 } 220 } 221 else 222 { 223 /* 224 * This method has called another method 225 * NOTE: the method call parse subtree is already deleted at 226 * this point, so we cannot disassemble the method invocation. 227 */ 228 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method ")); 229 AcpiDsPrintNodePathname (PreviousMethod, NULL); 230 } 231 232 PreviousMethod = NextWalkState->MethodNode; 233 NextWalkState = NextWalkState->Next; 234 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n")); 235 } 236 237 return_VOID; 238 } 239 240 #else 241 242 void 243 AcpiDsDumpMethodStack ( 244 ACPI_STATUS Status, 245 ACPI_WALK_STATE *WalkState, 246 ACPI_PARSE_OBJECT *Op) 247 { 248 return; 249 } 250 251 #endif 252