REORG: pool: move the area dump with symbol resolution to tools.c

This function is particularly useful to dump unknown areas watching
for opportunistic symbols, so let's move it to tools.c so that we can
reuse it a little bit more.
This commit is contained in:
Willy Tarreau 2024-04-12 16:18:34 +02:00
parent b21aaef4e5
commit 16e3655fbd
3 changed files with 55 additions and 43 deletions

View File

@ -1007,6 +1007,8 @@ int dump_binary(struct buffer *out, const char *buf, int bsize);
int dump_text_line(struct buffer *out, const char *buf, int bsize, int len,
int *line, int ptr);
void dump_addr_and_bytes(struct buffer *buf, const char *pfx, const void *addr, int n);
void dump_area_with_syms(struct buffer *output, const void *base, const void *addr,
const void *special, const char *spec_type, const char *spec_name);
void dump_hex(struct buffer *out, const char *pfx, const void *buf, int len, int unsafe);
int may_access(const void *ptr);
const void *resolve_sym_name(struct buffer *buf, const char *pfx, const void *addr);

View File

@ -1014,8 +1014,6 @@ void pool_inspect_item(const char *msg, struct pool_head *pool, const void *item
}
if (!the_pool) {
const char *start, *end, *p;
chunk_appendf(&trash,
"Tag does not match any other pool.\n");
@ -1025,47 +1023,7 @@ void pool_inspect_item(const char *msg, struct pool_head *pool, const void *item
else
chunk_appendf(&trash, " (no match).\n");
chunk_appendf(&trash,
"Contents around address %p+%lu=%p:\n",
item, (ulong)((const void*)pool_mark - (const void*)item),
pool_mark);
/* dump in word-sized blocks */
start = (const void *)(((uintptr_t)pool_mark - 32) & -sizeof(void*));
end = (const void *)(((uintptr_t)pool_mark + 32 + sizeof(void*) - 1) & -sizeof(void*));
while (start < end) {
dump_addr_and_bytes(&trash, " ", start, sizeof(void*));
chunk_strcat(&trash, " [");
for (p = start; p < start + sizeof(void*); p++) {
if (!may_access(p))
chunk_strcat(&trash, "*");
else if (isprint((unsigned char)*p))
chunk_appendf(&trash, "%c", *p);
else
chunk_strcat(&trash, ".");
}
if (may_access(start))
tag = *(const void **)start;
else
tag = NULL;
if (tag == pool) {
/* the pool can often be there so let's detect it */
chunk_appendf(&trash, "] [pool:%s", pool->name);
}
else if (tag) {
/* print pointers that resolve to a symbol */
size_t back_data = trash.data;
chunk_strcat(&trash, "] [");
if (!resolve_sym_name(&trash, NULL, tag))
trash.data = back_data;
}
chunk_strcat(&trash, "]\n");
start = p;
}
dump_area_with_syms(&trash, item, pool_mark, pool, "pool", pool->name);
}
}
}

View File

@ -4909,6 +4909,58 @@ void dump_addr_and_bytes(struct buffer *buf, const char *pfx, const void *addr,
}
}
/* Dumps the 64 bytes around <addr> at the end of <output> with symbols
* decoding. An optional special pointer may be recognized (special), in
* which case its type (spec_type) and name (spec_name) will be reported.
* This is convenient for pool names but could be used for list heads or
* anything in that vein.
*/
void dump_area_with_syms(struct buffer *output, const void *base, const void *addr,
const void *special, const char *spec_type, const char *spec_name)
{
const char *start, *end, *p;
const void *tag;
chunk_appendf(output, "Contents around address %p+%lu=%p:\n", base, (ulong)(addr - base), addr);
/* dump in word-sized blocks */
start = (const void *)(((uintptr_t)addr - 32) & -sizeof(void*));
end = (const void *)(((uintptr_t)addr + 32 + sizeof(void*) - 1) & -sizeof(void*));
while (start < end) {
dump_addr_and_bytes(output, " ", start, sizeof(void*));
chunk_strcat(output, " [");
for (p = start; p < start + sizeof(void*); p++) {
if (!may_access(p))
chunk_strcat(output, "*");
else if (isprint((unsigned char)*p))
chunk_appendf(output, "%c", *p);
else
chunk_strcat(output, ".");
}
if (may_access(start))
tag = *(const void **)start;
else
tag = NULL;
if (special && tag == special) {
/* the pool can often be there so let's detect it */
chunk_appendf(output, "] [%s:%s", spec_type, spec_name);
}
else if (tag) {
/* print pointers that resolve to a symbol */
size_t back_data = output->data;
chunk_strcat(output, "] [");
if (!resolve_sym_name(output, NULL, tag))
output->data = back_data;
}
chunk_strcat(output, "]\n");
start = p;
}
}
/* print a line of text buffer (limited to 70 bytes) to <out>. The format is :
* <2 spaces> <offset=5 digits> <space or plus> <space> <70 chars max> <\n>
* which is 60 chars per line. Non-printable chars \t, \n, \r and \e are