diff options
author | Chia-hung Duan <chiahungduan@google.com> | 2022-11-18 23:57:48 +0000 |
---|---|---|
committer | Chia-hung Duan <chiahungduan@google.com> | 2023-01-05 23:30:39 +0000 |
commit | 9bef28b362c5e905bd51512701b14510c116a5c1 (patch) | |
tree | 226721f6f97d36b8ac92eeb2de03fa3d1e243f65 /memory_replay | |
parent | 42a083665449dfa2b4f397562257fa8cced1753f (diff) | |
download | extras-9bef28b362c5e905bd51512701b14510c116a5c1.tar.gz |
Support parsing timestamp and split parsing out
The data structure of parsing can be shared with tool like memory_stats
which is used to analyze the alloc data
Test: Ran traces.
Change-Id: Id258d027cf2a1f9eb78cd511772cf932c96f4af5
Diffstat (limited to 'memory_replay')
-rw-r--r-- | memory_replay/Alloc.cpp | 59 | ||||
-rw-r--r-- | memory_replay/Alloc.h | 25 | ||||
-rw-r--r-- | memory_replay/AllocParser.cpp | 92 | ||||
-rw-r--r-- | memory_replay/AllocParser.h | 44 | ||||
-rw-r--r-- | memory_replay/Android.bp | 16 | ||||
-rw-r--r-- | memory_replay/File.cpp | 1 |
6 files changed, 155 insertions, 82 deletions
diff --git a/memory_replay/Alloc.cpp b/memory_replay/Alloc.cpp index af94ee5d..a6247105 100644 --- a/memory_replay/Alloc.cpp +++ b/memory_replay/Alloc.cpp @@ -14,72 +14,15 @@ * limitations under the License. */ -#include <err.h> -#include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <unistd.h> -#include <string> - #include "Alloc.h" +#include "AllocParser.h" #include "Pointers.h" #include "Utils.h" -void AllocGetData(const std::string& line, AllocEntry* entry) { - int line_pos = 0; - char name[128]; - // All lines have this format: - // TID: ALLOCATION_TYPE POINTER - // where - // TID is the thread id of the thread doing the operation. - // ALLOCATION_TYPE is one of malloc, calloc, memalign, realloc, free, thread_done - // POINTER is the hex value of the actual pointer - if (sscanf(line.c_str(), "%d: %127s %" SCNx64 " %n", &entry->tid, name, &entry->ptr, &line_pos) != - 3) { - errx(1, "File Error: Failed to process %s", line.c_str()); - } - const char* line_end = &line[line_pos]; - std::string type(name); - if (type == "malloc") { - // Format: - // TID: malloc POINTER SIZE_OF_ALLOCATION - if (sscanf(line_end, "%zu", &entry->size) != 1) { - errx(1, "File Error: Failed to read malloc data %s", line.c_str()); - } - entry->type = MALLOC; - } else if (type == "free") { - // Format: - // TID: free POINTER - entry->type = FREE; - } else if (type == "calloc") { - // Format: - // TID: calloc POINTER ITEM_COUNT ITEM_SIZE - if (sscanf(line_end, "%" SCNd64 " %zu", &entry->u.n_elements, &entry->size) != 2) { - errx(1, "File Error: Failed to read calloc data %s", line.c_str()); - } - entry->type = CALLOC; - } else if (type == "realloc") { - // Format: - // TID: calloc POINTER NEW_SIZE OLD_POINTER - if (sscanf(line_end, "%" SCNx64 " %zu", &entry->u.old_ptr, &entry->size) != 2) { - errx(1, "File Error: Failed to read realloc data %s", line.c_str()); - } - entry->type = REALLOC; - } else if (type == "memalign") { - // Format: - // TID: memalign POINTER ALIGNMENT SIZE - if (sscanf(line_end, "%" SCNd64 " %zu", &entry->u.align, &entry->size) != 2) { - errx(1, "File Error: Failed to read memalign data %s", line.c_str()); - } - entry->type = MEMALIGN; - } else if (type == "thread_done") { - entry->type = THREAD_DONE; - } else { - errx(1, "File Error: Unknown type %s", type.c_str()); - } -} - bool AllocDoesFree(const AllocEntry& entry) { switch (entry.type) { case MALLOC: diff --git a/memory_replay/Alloc.h b/memory_replay/Alloc.h index d590fcba..f4dcc83c 100644 --- a/memory_replay/Alloc.h +++ b/memory_replay/Alloc.h @@ -16,34 +16,11 @@ #pragma once -#include <string> +#include "AllocParser.h" // Forward Declarations. class Pointers; -enum AllocEnum : uint8_t { - MALLOC = 0, - CALLOC, - MEMALIGN, - REALLOC, - FREE, - THREAD_DONE, -}; - -struct AllocEntry { - pid_t tid; - AllocEnum type; - uint64_t ptr = 0; - size_t size = 0; - union { - uint64_t old_ptr = 0; - uint64_t n_elements; - uint64_t align; - } u; -}; - -void AllocGetData(const std::string& line, AllocEntry* entry); - bool AllocDoesFree(const AllocEntry& entry); uint64_t AllocExecute(const AllocEntry& entry, Pointers* pointers); diff --git a/memory_replay/AllocParser.cpp b/memory_replay/AllocParser.cpp new file mode 100644 index 00000000..ac6664a2 --- /dev/null +++ b/memory_replay/AllocParser.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <err.h> +#include <inttypes.h> +#include <stdio.h> + +#include "AllocParser.h" + +#include <iostream> + +void AllocGetData(const std::string& line, AllocEntry* entry) { + int op_prefix_pos = 0; + char name[128]; + // All lines have this format: + // TID: ALLOCATION_TYPE POINTER + // where + // TID is the thread id of the thread doing the operation. + // ALLOCATION_TYPE is one of malloc, calloc, memalign, realloc, free, thread_done + // POINTER is the hex value of the actual pointer + if (sscanf(line.c_str(), "%d: %127s %" SCNx64 " %n", &entry->tid, name, &entry->ptr, + &op_prefix_pos) != 3) { + errx(1, "File Error: Failed to process %s", line.c_str()); + } + std::string type(name); + if (type == "thread_done") { + entry->type = THREAD_DONE; + } else { + int args_offset = 0; + const char* args_beg = &line[op_prefix_pos]; + if (type == "malloc") { + // Format: + // TID: malloc POINTER SIZE_OF_ALLOCATION + if (sscanf(args_beg, "%zu%n", &entry->size, &args_offset) != 1) { + errx(1, "File Error: Failed to read malloc data %s", line.c_str()); + } + entry->type = MALLOC; + } else if (type == "free") { + // Format: + // TID: free POINTER + entry->type = FREE; + } else if (type == "calloc") { + // Format: + // TID: calloc POINTER ITEM_COUNT ITEM_SIZE + if (sscanf(args_beg, "%" SCNd64 " %zu%n", &entry->u.n_elements, &entry->size, + &args_offset) != 2) { + errx(1, "File Error: Failed to read calloc data %s", line.c_str()); + } + entry->type = CALLOC; + } else if (type == "realloc") { + // Format: + // TID: realloc POINTER OLD_POINTER NEW_SIZE + if (sscanf(args_beg, "%" SCNx64 " %zu%n", &entry->u.old_ptr, &entry->size, + &args_offset) != 2) { + errx(1, "File Error: Failed to read realloc data %s", line.c_str()); + } + entry->type = REALLOC; + } else if (type == "memalign") { + // Format: + // TID: memalign POINTER ALIGNMENT SIZE + if (sscanf(args_beg, "%" SCNd64 " %zu%n", &entry->u.align, &entry->size, + &args_offset) != 2) { + errx(1, "File Error: Failed to read memalign data %s", line.c_str()); + } + entry->type = MEMALIGN; + } else { + errx(1, "File Error: Unknown type %s", type.c_str()); + } + + const char* timestamps_beg = &args_beg[args_offset]; + + // Timestamps come after the alloc args if present, for example, + // TID: malloc POINTER SIZE_OF_ALLOCATION START_TIME END_TIME + int n_match = sscanf(timestamps_beg, "%" SCNd64 " %" SCNd64, &entry->st, &entry->et); + if (n_match != EOF && n_match != 2) { + errx(1, "File Error: Failed to read timestamps %s", line.c_str()); + } + } +} diff --git a/memory_replay/AllocParser.h b/memory_replay/AllocParser.h new file mode 100644 index 00000000..e7727b68 --- /dev/null +++ b/memory_replay/AllocParser.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <string> + +enum AllocEnum : uint8_t { + MALLOC = 0, + CALLOC, + MEMALIGN, + REALLOC, + FREE, + THREAD_DONE, +}; + +struct AllocEntry { + pid_t tid; + AllocEnum type; + uint64_t ptr = 0; + size_t size = 0; + union { + uint64_t old_ptr = 0; + uint64_t n_elements; + uint64_t align; + } u; + uint64_t st = 0; + uint64_t et = 0; +}; + +void AllocGetData(const std::string& line, AllocEntry* entry); diff --git a/memory_replay/Android.bp b/memory_replay/Android.bp index 8fb9dbc1..bdcde1b2 100644 --- a/memory_replay/Android.bp +++ b/memory_replay/Android.bp @@ -44,6 +44,17 @@ cc_defaults { compile_multilib: "both", } +cc_library_static { + name: "liballoc_parser", + host_supported: true, + defaults: ["memory_flag_defaults"], + + export_include_dirs: ["."], + srcs: [ + "AllocParser.cpp", + ], +} + cc_defaults { name: "memory_replay_defaults", defaults: ["memory_flag_defaults"], @@ -63,6 +74,7 @@ cc_defaults { ], static_libs: [ + "liballoc_parser", "libasync_safe", ], } @@ -126,6 +138,10 @@ cc_benchmark { "libziparchive", ], + static_libs: [ + "liballoc_parser", + ], + data: [ "traces/*.zip", ], diff --git a/memory_replay/File.cpp b/memory_replay/File.cpp index 8bcd9041..e44c5007 100644 --- a/memory_replay/File.cpp +++ b/memory_replay/File.cpp @@ -29,6 +29,7 @@ #include <ziparchive/zip_archive.h> #include "Alloc.h" +#include "AllocParser.h" #include "File.h" std::string ZipGetContents(const char* filename) { |