1 /******************************************************************************
2 *
3 * Module Name: dsdebug - Parser/Interpreter interface - debugging
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2016, 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
AcpiDsPrintNodePathname(ACPI_NAMESPACE_NODE * Node,const char * Message)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
AcpiDsDumpMethodStack(ACPI_STATUS Status,ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op)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 AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
216 #endif
217 Op->Common.Next = Next;
218 }
219 }
220 else
221 {
222 /*
223 * This method has called another method
224 * NOTE: the method call parse subtree is already deleted at
225 * this point, so we cannot disassemble the method invocation.
226 */
227 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method "));
228 AcpiDsPrintNodePathname (PreviousMethod, NULL);
229 }
230
231 PreviousMethod = NextWalkState->MethodNode;
232 NextWalkState = NextWalkState->Next;
233 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n"));
234 }
235
236 return_VOID;
237 }
238
239 #else
240
241 void
242 AcpiDsDumpMethodStack (
243 ACPI_STATUS Status,
244 ACPI_WALK_STATE *WalkState,
245 ACPI_PARSE_OBJECT *Op)
246 {
247 return;
248 }
249
250 #endif
251