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:
parent
b21aaef4e5
commit
16e3655fbd
@ -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);
|
||||
|
44
src/pool.c
44
src/pool.c
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
52
src/tools.c
52
src/tools.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user