Merge "Fix malloc_info missing large allocs."

This commit is contained in:
Christopher Ferris 2019-05-03 16:06:26 +00:00 committed by Gerrit Code Review
commit 2c02e45f4b
2 changed files with 62 additions and 8 deletions

View file

@ -128,10 +128,10 @@ int je_mallopt(int param, int value) {
__BEGIN_DECLS
size_t __mallinfo_narenas();
size_t __mallinfo_nbins();
struct mallinfo __mallinfo_arena_info(size_t);
struct mallinfo __mallinfo_bin_info(size_t, size_t);
size_t je_mallinfo_narenas();
size_t je_mallinfo_nbins();
struct mallinfo je_mallinfo_arena_info(size_t);
struct mallinfo je_mallinfo_bin_info(size_t, size_t);
__END_DECLS
@ -144,8 +144,8 @@ int je_malloc_info(int options, FILE* fp) {
MallocXmlElem root(fp, "malloc", "version=\"jemalloc-1\"");
// Dump all of the large allocations in the arenas.
for (size_t i = 0; i < __mallinfo_narenas(); i++) {
struct mallinfo mi = __mallinfo_arena_info(i);
for (size_t i = 0; i < je_mallinfo_narenas(); i++) {
struct mallinfo mi = je_mallinfo_arena_info(i);
if (mi.hblkhd != 0) {
MallocXmlElem arena_elem(fp, "heap", "nr=\"%d\"", i);
{
@ -154,8 +154,8 @@ int je_malloc_info(int options, FILE* fp) {
MallocXmlElem(fp, "allocated-bins").Contents("%zu", mi.fsmblks);
size_t total = 0;
for (size_t j = 0; j < __mallinfo_nbins(); j++) {
struct mallinfo mi = __mallinfo_bin_info(i, j);
for (size_t j = 0; j < je_mallinfo_nbins(); j++) {
struct mallinfo mi = je_mallinfo_bin_info(i, j);
if (mi.ordblks != 0) {
MallocXmlElem bin_elem(fp, "bin", "nr=\"%d\"", j);
MallocXmlElem(fp, "allocated").Contents("%zu", mi.ordblks);

View file

@ -395,6 +395,60 @@ TEST(malloc, malloc_info) {
#endif
}
TEST(malloc, malloc_info_matches_mallinfo) {
#ifdef __BIONIC__
SKIP_WITH_HWASAN; // hwasan does not implement malloc_info
char* buf;
size_t bufsize;
FILE* memstream = open_memstream(&buf, &bufsize);
ASSERT_NE(nullptr, memstream);
size_t mallinfo_before_allocated_bytes = mallinfo().uordblks;
ASSERT_EQ(0, malloc_info(0, memstream));
size_t mallinfo_after_allocated_bytes = mallinfo().uordblks;
ASSERT_EQ(0, fclose(memstream));
tinyxml2::XMLDocument doc;
ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buf));
size_t total_allocated_bytes = 0;
auto root = doc.FirstChildElement();
ASSERT_NE(nullptr, root);
ASSERT_STREQ("malloc", root->Name());
if (std::string(root->Attribute("version")) == "jemalloc-1") {
// Verify jemalloc version of this data.
ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
auto arena = root->FirstChildElement();
for (; arena != nullptr; arena = arena->NextSiblingElement()) {
int val;
ASSERT_STREQ("heap", arena->Name());
ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
ASSERT_EQ(tinyxml2::XML_SUCCESS,
arena->FirstChildElement("allocated-large")->QueryIntText(&val));
total_allocated_bytes += val;
ASSERT_EQ(tinyxml2::XML_SUCCESS,
arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
total_allocated_bytes += val;
ASSERT_EQ(tinyxml2::XML_SUCCESS,
arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
total_allocated_bytes += val;
ASSERT_EQ(tinyxml2::XML_SUCCESS,
arena->FirstChildElement("bins-total")->QueryIntText(&val));
}
// The total needs to be between the mallinfo call before and after
// since malloc_info allocates some memory.
EXPECT_LE(mallinfo_before_allocated_bytes, total_allocated_bytes);
EXPECT_GE(mallinfo_after_allocated_bytes, total_allocated_bytes);
} else {
// Only verify that this is debug-malloc-1, the malloc debug unit tests
// verify the output.
ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
}
#endif
}
TEST(malloc, calloc_usable_size) {
for (size_t size = 1; size <= 2048; size++) {
void* pointer = malloc(size);