Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure
@@ -3,11 +3,11 @@
* Module Name: uttrack - Memory allocation tracking routines (debug only)
*
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2011, Intel Corp.
+ * Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -60,15 +60,16 @@
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("uttrack")
+
/* Local prototypes */
static ACPI_DEBUG_MEM_BLOCK *
AcpiUtFindAllocation (
- void *Allocation);
+ ACPI_DEBUG_MEM_BLOCK *Allocation);
static ACPI_STATUS
AcpiUtTrackAllocation (
ACPI_DEBUG_MEM_BLOCK *Address,
ACPI_SIZE Size,
@@ -148,14 +149,27 @@
{
ACPI_DEBUG_MEM_BLOCK *Allocation;
ACPI_STATUS Status;
- Allocation = AcpiUtAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER),
- Component, Module, Line);
+ /* Check for an inadvertent size of zero bytes */
+
+ if (!Size)
+ {
+ ACPI_WARNING ((Module, Line,
+ "Attempt to allocate zero bytes, allocating 1 byte"));
+ Size = 1;
+ }
+
+ Allocation = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER));
if (!Allocation)
{
+ /* Report allocation error */
+
+ ACPI_WARNING ((Module, Line,
+ "Could not allocate size %u", (UINT32) Size));
+
return (NULL);
}
Status = AcpiUtTrackAllocation (Allocation, Size,
ACPI_MEM_MALLOC, Component, Module, Line);
@@ -201,12 +215,20 @@
{
ACPI_DEBUG_MEM_BLOCK *Allocation;
ACPI_STATUS Status;
- Allocation = AcpiUtAllocateZeroed (Size + sizeof (ACPI_DEBUG_MEM_HEADER),
- Component, Module, Line);
+ /* Check for an inadvertent size of zero bytes */
+
+ if (!Size)
+ {
+ ACPI_WARNING ((Module, Line,
+ "Attempt to allocate zero bytes, allocating 1 byte"));
+ Size = 1;
+ }
+
+ Allocation = AcpiOsAllocateZeroed (Size + sizeof (ACPI_DEBUG_MEM_HEADER));
if (!Allocation)
{
/* Report allocation error */
ACPI_ERROR ((Module, Line,
@@ -283,11 +305,12 @@
{
ACPI_EXCEPTION ((AE_INFO, Status, "Could not free memory"));
}
AcpiOsFree (DebugBlock);
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", Allocation));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n",
+ Allocation, DebugBlock));
return_VOID;
}
/*******************************************************************************
@@ -294,41 +317,69 @@
*
* FUNCTION: AcpiUtFindAllocation
*
* PARAMETERS: Allocation - Address of allocated memory
*
- * RETURN: A list element if found; NULL otherwise.
+ * RETURN: Three cases:
+ * 1) List is empty, NULL is returned.
+ * 2) Element was found. Returns Allocation parameter.
+ * 3) Element was not found. Returns position where it should be
+ * inserted into the list.
*
* DESCRIPTION: Searches for an element in the global allocation tracking list.
+ * If the element is not found, returns the location within the
+ * list where the element should be inserted.
*
+ * Note: The list is ordered by larger-to-smaller addresses.
+ *
+ * This global list is used to detect memory leaks in ACPICA as
+ * well as other issues such as an attempt to release the same
+ * internal object more than once. Although expensive as far
+ * as cpu time, this list is much more helpful for finding these
+ * types of issues than using memory leak detectors outside of
+ * the ACPICA code.
+ *
******************************************************************************/
static ACPI_DEBUG_MEM_BLOCK *
AcpiUtFindAllocation (
- void *Allocation)
+ ACPI_DEBUG_MEM_BLOCK *Allocation)
{
ACPI_DEBUG_MEM_BLOCK *Element;
- ACPI_FUNCTION_ENTRY ();
-
-
Element = AcpiGbl_GlobalList->ListHead;
+ if (!Element)
+ {
+ return (NULL);
+ }
- /* Search for the address. */
+ /*
+ * Search for the address.
+ *
+ * Note: List is ordered by larger-to-smaller addresses, on the
+ * assumption that a new allocation usually has a larger address
+ * than previous allocations.
+ */
+ while (Element > Allocation)
+ {
+ /* Check for end-of-list */
- while (Element)
+ if (!Element->Next)
{
- if (Element == Allocation)
- {
return (Element);
}
Element = Element->Next;
}
- return (NULL);
+ if (Element == Allocation)
+ {
+ return (Element);
+ }
+
+ return (Element->Previous);
}
/*******************************************************************************
*
@@ -339,11 +390,11 @@
* AllocType - MEM_MALLOC or MEM_CALLOC
* Component - Component type of caller
* Module - Source file name of caller
* Line - Line number of caller
*
- * RETURN: None.
+ * RETURN: Status
*
* DESCRIPTION: Inserts an element into the global allocation tracking list.
*
******************************************************************************/
@@ -375,36 +426,34 @@
{
return_ACPI_STATUS (Status);
}
/*
- * Search list for this address to make sure it is not already on the list.
- * This will catch several kinds of problems.
+ * Search the global list for this address to make sure it is not
+ * already present. This will catch several kinds of problems.
*/
Element = AcpiUtFindAllocation (Allocation);
- if (Element)
+ if (Element == Allocation)
{
ACPI_ERROR ((AE_INFO,
- "UtTrackAllocation: Allocation already present in list! (%p)",
+ "UtTrackAllocation: Allocation (%p) already present in global list!",
Allocation));
-
- ACPI_ERROR ((AE_INFO, "Element %p Address %p",
- Element, Allocation));
-
goto UnlockAndExit;
}
- /* Fill in the instance data. */
+ /* Fill in the instance data */
Allocation->Size = (UINT32) Size;
Allocation->AllocType = AllocType;
Allocation->Component = Component;
Allocation->Line = Line;
ACPI_STRNCPY (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0;
+ if (!Element)
+ {
/* Insert at list head */
if (MemList->ListHead)
{
((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Allocation;
@@ -412,12 +461,27 @@
Allocation->Next = MemList->ListHead;
Allocation->Previous = NULL;
MemList->ListHead = Allocation;
+ }
+ else
+ {
+ /* Insert after element */
+ Allocation->Next = Element->Next;
+ Allocation->Previous = Element;
+ if (Element->Next)
+ {
+ (Element->Next)->Previous = Allocation;
+ }
+
+ Element->Next = Allocation;
+ }
+
+
UnlockAndExit:
Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
return_ACPI_STATUS (Status);
}
@@ -429,11 +493,11 @@
* PARAMETERS: Allocation - Address of allocated memory
* Component - Component type of caller
* Module - Source file name of caller
* Line - Line number of caller
*
- * RETURN:
+ * RETURN: Status
*
* DESCRIPTION: Deletes an element from the global allocation tracking list.
*
******************************************************************************/
@@ -446,16 +510,16 @@
{
ACPI_MEMORY_LIST *MemList;
ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (UtRemoveAllocation);
+ ACPI_FUNCTION_NAME (UtRemoveAllocation);
if (AcpiGbl_DisableMemTracking)
{
- return_ACPI_STATUS (AE_OK);
+ return (AE_OK);
}
MemList = AcpiGbl_GlobalList;
if (NULL == MemList->ListHead)
{
@@ -462,17 +526,17 @@
/* No allocations! */
ACPI_ERROR ((Module, Line,
"Empty allocation list, nothing to free!"));
- return_ACPI_STATUS (AE_OK);
+ return (AE_OK);
}
Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
if (ACPI_FAILURE (Status))
{
- return_ACPI_STATUS (Status);
+ return (Status);
}
/* Unlink */
if (Allocation->Previous)
@@ -487,27 +551,27 @@
if (Allocation->Next)
{
(Allocation->Next)->Previous = Allocation->Previous;
}
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n",
+ &Allocation->UserSpace, Allocation->Size));
+
/* Mark the segment as deleted */
ACPI_MEMSET (&Allocation->UserSpace, 0xEA, Allocation->Size);
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
- Allocation->Size));
-
Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
- return_ACPI_STATUS (Status);
+ return (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiUtDumpAllocationInfo
*
- * PARAMETERS:
+ * PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Print some info about the outstanding allocations.
*
@@ -588,19 +652,19 @@
ACPI_FUNCTION_TRACE (UtDumpAllocations);
if (AcpiGbl_DisableMemTracking)
{
- return;
+ return_VOID;
}
/*
* Walk the allocation list.
*/
if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY)))
{
- return;
+ return_VOID;
}
Element = AcpiGbl_GlobalList->ListHead;
while (Element)
{
@@ -631,55 +695,63 @@
DescriptorType = 0; /* Not a valid descriptor type */
switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor))
{
case ACPI_DESC_TYPE_OPERAND:
- if (Element->Size == sizeof (ACPI_DESC_TYPE_OPERAND))
+
+ if (Element->Size == sizeof (ACPI_OPERAND_OBJECT))
{
DescriptorType = ACPI_DESC_TYPE_OPERAND;
}
break;
case ACPI_DESC_TYPE_PARSER:
- if (Element->Size == sizeof (ACPI_DESC_TYPE_PARSER))
+
+ if (Element->Size == sizeof (ACPI_PARSE_OBJECT))
{
DescriptorType = ACPI_DESC_TYPE_PARSER;
}
break;
case ACPI_DESC_TYPE_NAMED:
- if (Element->Size == sizeof (ACPI_DESC_TYPE_NAMED))
+
+ if (Element->Size == sizeof (ACPI_NAMESPACE_NODE))
{
DescriptorType = ACPI_DESC_TYPE_NAMED;
}
break;
default:
+
break;
}
/* Display additional info for the major descriptor types */
switch (DescriptorType)
{
case ACPI_DESC_TYPE_OPERAND:
+
AcpiOsPrintf ("%12.12s RefCount 0x%04X\n",
AcpiUtGetTypeName (Descriptor->Object.Common.Type),
Descriptor->Object.Common.ReferenceCount);
break;
case ACPI_DESC_TYPE_PARSER:
+
AcpiOsPrintf ("AmlOpcode 0x%04hX\n",
Descriptor->Op.Asl.AmlOpcode);
break;
case ACPI_DESC_TYPE_NAMED:
+
AcpiOsPrintf ("%4.4s\n",
AcpiUtGetNodeName (&Descriptor->Node));
break;
default:
+
AcpiOsPrintf ( "\n");
break;
}
}
}
@@ -706,6 +778,5 @@
return_VOID;
}
#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
-