* Extract malloc(9) statistics from the running kernel, and store all memory * type information in the passed list. For each type, check the list for an * existing entry with the right name/allocator -- if present, update that * entry. Otherwise, add a new entry. On error, the entire list will be * cleared, as entries will be in an inconsistent state. * * To reduce the level of work for a
| 85 | * each entry before adding it. |
| 86 | */ |
| 87 | int |
| 88 | memstat_sysctl_malloc(struct memory_type_list *list, int flags) |
| 89 | { |
| 90 | struct malloc_type_stream_header *mtshp; |
| 91 | struct malloc_type_header *mthp; |
| 92 | struct malloc_type_stats *mtsp; |
| 93 | struct memory_type *mtp; |
| 94 | int count, hint_dontsearch, i, j, maxcpus; |
| 95 | char *buffer, *p; |
| 96 | size_t size; |
| 97 | |
| 98 | hint_dontsearch = LIST_EMPTY(&list->mtl_list); |
| 99 | |
| 100 | /* |
| 101 | * Query the number of CPUs, number of malloc types so that we can |
| 102 | * guess an initial buffer size. We loop until we succeed or really |
| 103 | * fail. Note that the value of maxcpus we query using sysctl is not |
| 104 | * the version we use when processing the real data -- that is read |
| 105 | * from the header. |
| 106 | */ |
| 107 | retry: |
| 108 | size = sizeof(maxcpus); |
| 109 | if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) { |
| 110 | if (errno == EACCES || errno == EPERM) |
| 111 | list->mtl_error = MEMSTAT_ERROR_PERMISSION; |
| 112 | else |
| 113 | list->mtl_error = MEMSTAT_ERROR_DATAERROR; |
| 114 | return (-1); |
| 115 | } |
| 116 | if (size != sizeof(maxcpus)) { |
| 117 | list->mtl_error = MEMSTAT_ERROR_DATAERROR; |
| 118 | return (-1); |
| 119 | } |
| 120 | |
| 121 | size = sizeof(count); |
| 122 | if (sysctlbyname("kern.malloc_count", &count, &size, NULL, 0) < 0) { |
| 123 | if (errno == EACCES || errno == EPERM) |
| 124 | list->mtl_error = MEMSTAT_ERROR_PERMISSION; |
| 125 | else |
| 126 | list->mtl_error = MEMSTAT_ERROR_VERSION; |
| 127 | return (-1); |
| 128 | } |
| 129 | if (size != sizeof(count)) { |
| 130 | list->mtl_error = MEMSTAT_ERROR_DATAERROR; |
| 131 | return (-1); |
| 132 | } |
| 133 | |
| 134 | #ifndef FSTACK |
| 135 | if (memstat_malloc_zone_init() == -1) { |
| 136 | list->mtl_error = MEMSTAT_ERROR_VERSION; |
| 137 | return (-1); |
| 138 | } |
| 139 | #endif |
| 140 | |
| 141 | size = sizeof(*mthp) + count * (sizeof(*mthp) + sizeof(*mtsp) * |
| 142 | maxcpus); |
| 143 | |
| 144 | buffer = malloc(size); |
no test coverage detected