Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: dsdebug - Parser/Interpreter interface - debugging
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acdispat.h"
0013 #include "acnamesp.h"
0014 #ifdef ACPI_DISASSEMBLER
0015 #include "acdisasm.h"
0016 #endif
0017 #include "acinterp.h"
0018 
0019 #define _COMPONENT          ACPI_DISPATCHER
0020 ACPI_MODULE_NAME("dsdebug")
0021 
0022 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
0023 /* Local prototypes */
0024 static void
0025 acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
0026                 const char *message);
0027 
0028 /*******************************************************************************
0029  *
0030  * FUNCTION:    acpi_ds_print_node_pathname
0031  *
0032  * PARAMETERS:  node            - Object
0033  *              message         - Prefix message
0034  *
0035  * DESCRIPTION: Print an object's full namespace pathname
0036  *              Manages allocation/freeing of a pathname buffer
0037  *
0038  ******************************************************************************/
0039 
0040 static void
0041 acpi_ds_print_node_pathname(struct acpi_namespace_node *node,
0042                 const char *message)
0043 {
0044     struct acpi_buffer buffer;
0045     acpi_status status;
0046 
0047     ACPI_FUNCTION_TRACE(ds_print_node_pathname);
0048 
0049     if (!node) {
0050         ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]"));
0051         return_VOID;
0052     }
0053 
0054     /* Convert handle to full pathname and print it (with supplied message) */
0055 
0056     buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0057 
0058     status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
0059     if (ACPI_SUCCESS(status)) {
0060         if (message) {
0061             ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ",
0062                           message));
0063         }
0064 
0065         ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[%s] (Node %p)",
0066                       (char *)buffer.pointer, node));
0067         ACPI_FREE(buffer.pointer);
0068     }
0069 
0070     return_VOID;
0071 }
0072 
0073 /*******************************************************************************
0074  *
0075  * FUNCTION:    acpi_ds_dump_method_stack
0076  *
0077  * PARAMETERS:  status          - Method execution status
0078  *              walk_state      - Current state of the parse tree walk
0079  *              op              - Executing parse op
0080  *
0081  * RETURN:      None
0082  *
0083  * DESCRIPTION: Called when a method has been aborted because of an error.
0084  *              Dumps the method execution stack.
0085  *
0086  ******************************************************************************/
0087 
0088 void
0089 acpi_ds_dump_method_stack(acpi_status status,
0090               struct acpi_walk_state *walk_state,
0091               union acpi_parse_object *op)
0092 {
0093     union acpi_parse_object *next;
0094     struct acpi_thread_state *thread;
0095     struct acpi_walk_state *next_walk_state;
0096     struct acpi_namespace_node *previous_method = NULL;
0097     union acpi_operand_object *method_desc;
0098 
0099     ACPI_FUNCTION_TRACE(ds_dump_method_stack);
0100 
0101     /* Ignore control codes, they are not errors */
0102 
0103     if (ACPI_CNTL_EXCEPTION(status)) {
0104         return_VOID;
0105     }
0106 
0107     /* We may be executing a deferred opcode */
0108 
0109     if (walk_state->deferred_node) {
0110         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0111                   "Executing subtree for Buffer/Package/Region\n"));
0112         return_VOID;
0113     }
0114 
0115     /*
0116      * If there is no Thread, we are not actually executing a method.
0117      * This can happen when the iASL compiler calls the interpreter
0118      * to perform constant folding.
0119      */
0120     thread = walk_state->thread;
0121     if (!thread) {
0122         return_VOID;
0123     }
0124 
0125     /* Display exception and method name */
0126 
0127     ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0128               "\n**** Exception %s during execution of method ",
0129               acpi_format_exception(status)));
0130 
0131     acpi_ds_print_node_pathname(walk_state->method_node, NULL);
0132 
0133     /* Display stack of executing methods */
0134 
0135     ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
0136                   "\n\nMethod Execution Stack:\n"));
0137     next_walk_state = thread->walk_state_list;
0138 
0139     /* Walk list of linked walk states */
0140 
0141     while (next_walk_state) {
0142         method_desc = next_walk_state->method_desc;
0143         if (method_desc) {
0144             acpi_ex_stop_trace_method((struct acpi_namespace_node *)
0145                           method_desc->method.node,
0146                           method_desc, walk_state);
0147         }
0148 
0149         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0150                   "    Method [%4.4s] executing: ",
0151                   acpi_ut_get_node_name(next_walk_state->
0152                             method_node)));
0153 
0154         /* First method is the currently executing method */
0155 
0156         if (next_walk_state == walk_state) {
0157             if (op) {
0158 
0159                 /* Display currently executing ASL statement */
0160 
0161                 next = op->common.next;
0162                 op->common.next = NULL;
0163 
0164 #ifdef ACPI_DISASSEMBLER
0165                 if (walk_state->method_node !=
0166                     acpi_gbl_root_node) {
0167 
0168                     /* More verbose if not module-level code */
0169 
0170                     acpi_os_printf("Failed at ");
0171                     acpi_dm_disassemble(next_walk_state, op,
0172                                 ACPI_UINT32_MAX);
0173                 }
0174 #endif
0175                 op->common.next = next;
0176             }
0177         } else {
0178             /*
0179              * This method has called another method
0180              * NOTE: the method call parse subtree is already deleted at
0181              * this point, so we cannot disassemble the method invocation.
0182              */
0183             ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH,
0184                           "Call to method "));
0185             acpi_ds_print_node_pathname(previous_method, NULL);
0186         }
0187 
0188         previous_method = next_walk_state->method_node;
0189         next_walk_state = next_walk_state->next;
0190         ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n"));
0191     }
0192 
0193     return_VOID;
0194 }
0195 
0196 #else
0197 void
0198 acpi_ds_dump_method_stack(acpi_status status,
0199               struct acpi_walk_state *walk_state,
0200               union acpi_parse_object *op)
0201 {
0202     return;
0203 }
0204 
0205 #endif