]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: pool: move the area dump with symbol resolution to tools.c
authorWilly Tarreau <w@1wt.eu>
Fri, 12 Apr 2024 14:18:34 +0000 (16:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 12 Apr 2024 16:01:20 +0000 (18:01 +0200)
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.

include/haproxy/tools.h
src/pool.c
src/tools.c

index d76b2d13c85654aa1cbb17845bd0876763d4067a..11082379c8d2c1d86cb1c6fd0adf4b12ef1251cd 100644 (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);
index 65751b0dc3b299e0c15806f8e26b3f4e447cbd47..cc85faff317e7ef3ffadb4b69711c95c192fd07b 100644 (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);
                        }
                }
        }
index b08fb18ce5d669d8480b7f524192c55fd7e6d802..09de5db20100b8166e27b5576ac1455e93e3f960 100644 (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