[PATCH] dbghelp: use a buffer ring instead of single buffer for fetch_buffer

Eric Pouech eric.pouech at gmail.com
Thu Jul 22 02:38:23 CDT 2021


as reported by Alistair, SymGetLineFromAddrW64 requires at least two buffers

I suggest using this patch instead of Alistair's, because:
- it doesn't duplicate internal lookup functions between A and W versions
- it's more robust against future use of fetch_buffer

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 dlls/dbghelp/dbghelp.c         |   18 ++++++++++++------
 dlls/dbghelp/dbghelp_private.h |   11 +++++++++--
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c
index 00d7b61fbd8..af8cf17741c 100644
--- a/dlls/dbghelp/dbghelp.c
+++ b/dlls/dbghelp/dbghelp.c
@@ -118,15 +118,21 @@ BOOL validate_addr64(DWORD64 addr)
  */
 void* fetch_buffer(struct process* pcs, unsigned size)
 {
-    if (size > pcs->buffer_size)
+    struct process_buffer* pb = &pcs->buffers[pcs->buffers_index];
+
+    if (size > pb->size)
     {
-        if (pcs->buffer)
-            pcs->buffer = HeapReAlloc(GetProcessHeap(), 0, pcs->buffer, size);
+        void* new;
+        if (pb->ptr)
+            new = HeapReAlloc(GetProcessHeap(), 0, pb->ptr, size);
         else
-            pcs->buffer = HeapAlloc(GetProcessHeap(), 0, size);
-        pcs->buffer_size = (pcs->buffer) ? size : 0;
+            new = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!new) return NULL;
+        pb->size = size;
+        pb->ptr = new;
     }
-    return pcs->buffer;
+    pcs->buffers_index = (pcs->buffers_index + 1) % ARRAY_SIZE(pcs->buffers);
+    return pb->ptr;
 }
 
 const char* wine_dbgstr_addr(const ADDRESS64* addr)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 3415fc1557c..cc74d0c1edc 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -397,6 +397,12 @@ struct loader_ops
     BOOL (*fetch_file_info)(struct process* process, const WCHAR* name, ULONG_PTR load_addr, DWORD_PTR* base, DWORD* size, DWORD* checksum);
 };
 
+struct process_buffer
+{
+    unsigned                    size;
+    void*                       ptr;
+};
+
 struct process 
 {
     struct process*             next;
@@ -415,8 +421,9 @@ struct process
 
     IMAGEHLP_STACK_FRAME        ctx_frame;
 
-    unsigned                    buffer_size;
-    void*                       buffer;
+    /* buffer:s ring */
+    struct process_buffer       buffers[2];
+    unsigned                    buffers_index;
 
     BOOL                        is_64bit;
 };




More information about the wine-devel mailing list