dsdebug.c revision 285728
1/******************************************************************************
2 *
3 * Module Name: dsdebug - Parser/Interpreter interface - debugging
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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
60static void
61AcpiDsPrintNodePathname (
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
78static void
79AcpiDsPrintNodePathname (
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, FALSE);
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
131void
132AcpiDsDumpMethodStack (
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    AcpiDsPrintNodePathname (WalkState->MethodNode, NULL);
179
180    /* Display stack of executing methods */
181
182    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH,
183        "\n\nMethod Execution Stack:\n"));
184    NextWalkState = Thread->WalkStateList;
185
186    /* Walk list of linked walk states */
187
188    while (NextWalkState)
189    {
190        MethodDesc = NextWalkState->MethodDesc;
191        if (MethodDesc)
192        {
193            AcpiExStopTraceMethod (
194                    (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node,
195                    MethodDesc, WalkState);
196        }
197
198        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
199            "    Method [%4.4s] executing: ",
200            AcpiUtGetNodeName (NextWalkState->MethodNode)));
201
202        /* First method is the currently executing method */
203
204        if (NextWalkState == WalkState)
205        {
206            if (Op)
207            {
208                /* Display currently executing ASL statement */
209
210                Next = Op->Common.Next;
211                Op->Common.Next = NULL;
212
213#ifdef ACPI_DISASSEMBLER
214                AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
215#endif
216                Op->Common.Next = Next;
217            }
218        }
219        else
220        {
221            /*
222             * This method has called another method
223             * NOTE: the method call parse subtree is already deleted at this
224             * point, so we cannot disassemble the method invocation.
225             */
226            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method "));
227            AcpiDsPrintNodePathname (PreviousMethod, NULL);
228        }
229
230        PreviousMethod = NextWalkState->MethodNode;
231        NextWalkState = NextWalkState->Next;
232        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n"));
233    }
234
235    return_VOID;
236}
237
238#else
239
240void
241AcpiDsDumpMethodStack (
242    ACPI_STATUS             Status,
243    ACPI_WALK_STATE         *WalkState,
244    ACPI_PARSE_OBJECT       *Op)
245{
246    return;
247}
248
249#endif
250