Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vEvP6-003mv3-NY for pgsql-hackers@arkaria.postgresql.org; Fri, 31 Oct 2025 20:07:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1vEvP5-000Mfj-LB for pgsql-hackers@arkaria.postgresql.org; Fri, 31 Oct 2025 20:07:18 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vEvP5-000Mfb-Af for pgsql-hackers@lists.postgresql.org; Fri, 31 Oct 2025 20:07:18 +0000 Received: from mail-yx1-xb12d.google.com ([2607:f8b0:4864:20::b12d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vEvP1-005ItQ-3C for pgsql-hackers@postgresql.org; Fri, 31 Oct 2025 20:07:18 +0000 Received: by mail-yx1-xb12d.google.com with SMTP id 956f58d0204a3-63e336b1ac4so4472282d50.1 for ; Fri, 31 Oct 2025 13:07:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761941234; x=1762546034; darn=postgresql.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=kiS7B0Rbve4V1u8hb/CYXAKWNtF2PFMQ43Zt+zgHK2g=; b=Hy3eVnoDXSNXSlmlDnPt6ryC20NjOkk21Hx97gObIaPldamEySzLXJzBUnE9sslRln ni9hJLfs4Bs5SngOY1kx3kM8e+dN9YF01GqZb0iGTxF8gmDwtzyz+8sa0SVLaZ15XZvK 4+L7hQiJ59Cd49aiAwy/hbJqw5zpsLAZa6aQFRXVl9uK82LPxOxirVSS45b8V5LBl22d Fu15IJfyEmDqG8w+4+fst4C8YcwKzWpOGb3558V1cFyBK0qJzfxHKbgbQgfFZsDYENf1 pTxtvWTozLTJEDY+vvuVI/TimUPlCd+lO3P4FkXBejOoCUpwnv40TagPHHF43byNuuQB nCNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761941234; x=1762546034; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kiS7B0Rbve4V1u8hb/CYXAKWNtF2PFMQ43Zt+zgHK2g=; b=muTWpZJt6HcUPTbz/uV/eEahSRXHszPNgf7aiLVAeAwq83jGQo0KicqKUhPGG3SELJ oPImt3fo5T0gcpr+iAymaVin+3WNYyYTBdJHkaMVcrphN4maK48WiLrCEN86wMvYzYp3 QeaaERlZbcdJU43AQYyJ0yKqXG/OSil8TKfugAKiBM/wFVQgUu0g4RnyyfEmYo+XkVsY v3R06gsG/znEUJNJxXgvPIGRuO5XlqhDDVo8GepnmLYsCOG5H3YTV4CUPlCTicNVcoiL wCOgVLH1gKw+EVo9yCQSET8NZwJL2zlwFsaoWRBkocyBCqsb1hhC3+2jsFJrPIxiH8m7 mrGA== X-Forwarded-Encrypted: i=1; AJvYcCXlXaYUcgGfukRUZ9q+Kw1yreeGy+Gi/cdblt7hLsxxn/9ERh17Q2SsMDXCt5ck7wWe9lbm1meYanpGZkyp@postgresql.org X-Gm-Message-State: AOJu0Yw9JxFHg4scnf42GuSOWrUijJZnSfpieuYZpZZRf3+b7q5ZVQTf QPudjgDBU2g/H4X085qmug/cWfsSf9/U6WoU+/TYiXEibsMmiBewQQD2 X-Gm-Gg: ASbGnctWKq2VEkZquaVvtBn3jTl+gOkiCOi45LSNC3ep+S5VWYoA5twKDLM52Ea+F5Y msk6meSxcpshQ+22tG1uCiN7sYvwdfDnGGI1IGXwFiFPec6KFULo05mzjDA+h71K08qYZE1L1qc fRfjL3X2h15YBoxlSvjveEPqOXnQskRiitUNmqQS6dN84iA3MIZBUNQ1SU/SoD49SGMJ479ODyQ /9ap/tlng2EtFuSRL+lwuHpNii9r9jNrtcKovWjSeobj45I0u3Ie6brNwbMx6Pr2ctKFcEmdYcS BsZk6p1lyNcnqcAhdqrOjhiqJs9yk1Uva8STwW7WOAjsGCcM8kWfxV8GKD0k1ZcJZsD9PzxJE/9 nSA8ADB0PE71jvdpY9siDvOOxPrHLC/ywigcRQbTSwX01joa4p6lykKt0wqyGce08WphMvXJRmU 7OxO610+vZRir5D5h1f+Vy24icYBXP33PcvWHthEp3Onaz2874K2OxH4MBCibXS45R X-Google-Smtp-Source: AGHT+IFd8lgrco2no3bJHQY2UiJzdwjGIlx1JjDRZelVXCZQbFBHZn84DHsu5yJCia0km461cwsSvQ== X-Received: by 2002:a05:690e:4148:b0:63e:1113:bde2 with SMTP id 956f58d0204a3-63f829a6435mr6148789d50.20.1761941234163; Fri, 31 Oct 2025 13:07:14 -0700 (PDT) Received: from ?IPV6:2600:1700:8952:80:b945:693f:d5d2:6c5e? ([2600:1700:8952:80:b945:693f:d5d2:6c5e]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7864c6a838bsm8043957b3.55.2025.10.31.13.07.13 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 31 Oct 2025 13:07:13 -0700 (PDT) Message-ID: Date: Fri, 31 Oct 2025 14:07:18 -0600 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] Add Windows support for backtrace_functions (MSVC only) To: Euler Taveira , Jakub Wartak Cc: =?UTF-8?Q?=C3=81lvaro_Herrera?= , Michael Paquier , pgsql-hackers References: <202510300932.isdvgkzqzshk@alvherre.pgsql> <5b4c6ce0-ed17-4abb-9127-859cc95cbdf3@gmail.com> <30aea073-109c-43cc-979c-081b922d055d@gmail.com> <2241662b-da7d-428f-beba-a416ef48e9e9@app.fastmail.com> Content-Language: en-US From: Bryan Green In-Reply-To: <2241662b-da7d-428f-beba-a416ef48e9e9@app.fastmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 10/31/2025 1:46 PM, Euler Taveira wrote: > On Thu, Oct 30, 2025, at 11:51 AM, Bryan Green wrote: >> I had reservations about the value the tests were adding, and >> considering I am getting more concern around having the tests than not >> having them for this initial release I have decided to remove them. v4 >> patch is attached. It is the same as the initial 0001-* patch. >> > > I spent some time on this patch. Here are some comments and suggestions. > Thanks for the review. > +#ifdef _MSC_VER > +#include > +#include > +static bool win32_backtrace_symbols_initialized = false; > +static HANDLE win32_backtrace_process = NULL; > +#endif > > We usually a different style. Headers go to the top on the same section as > system headers and below postgres.h. It is generally kept sorted. The same Will fix. I will rework the style (error and otherwise) to follow the project tradition. > applies to variables. Add them near the other static variables. BTW does it need > the win32_ prefix for a Window-only variable? > > + wchar_t buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(wchar_t)]; > + PSYMBOL_INFOW symbol; > > According to [1], SYMBOL_INFO is an alias that automatically selects ANSI vs > UNICODE. Shouldn't we use it instead of SYMBOL_INFOW? > Good point. I was being overly explicit about wanting wide chars, but you're right that the generic versions are the way to go. > + elog(WARNING, "SymInitialize failed with error %lu", error); > > Is there a reason to continue if SymInitialize failed? It should return after None at all. Will return immediately. > printing the message. Per the error message style guide [2], my suggestion is > "could not initialize the symbol handler: error code %lu". You can also use > GetLastError() directly in the elog call. > > + symbol = (PSYMBOL_INFOW) buffer; > + symbol ->MaxNameLen = MAX_SYM_NAME; > + symbol ->SizeOfStruct = sizeof(SYMBOL_INFOW); > > We generally don't add spaces between variable and a member. > > + DWORD i; > > I'm curious why did you declare this variable as DWORD? Shouldn't int be > sufficient? The CaptureStackBackTrace function returns an unsigned short > (UShort). You can also declare it in the for loop. > Out of habit. I will change it to int. > + DWORD64 address = (DWORD64) (stack[i]); > > The parenthesis around stack is superfluous. The code usually doesn't contain > additional parenthesis (unless it improves readability). > I will remove the parenthesis. > + if (frames == 0) > + { > + appendStringInfoString(&errtrace, "\nNo stack frames captured"); > + edata->backtrace = errtrace.data; > + return; > + } > > It seems CaptureStackBackTrace function may return zero frames under certain > conditions. It is a good point having this additional message. I noticed that > the current code path (HAVE_BACKTRACE_SYMBOLS) doesn't have this block. IIUC, > in certain circumstances (ARM vs unwind-tables flag), the backtrace() also > returns zero frames. Should we add this block for the backtrace() code path? > Probably, though that seems like separate cleanup. Want me to include it here or handle separately (in another patch)? > + sym_result = SymFromAddrW(win32_backtrace_process, > + address, > + &displacement, > + symbol); > > You should use SymFromAddr, no? [3] I saw that you used the Unicode functions > instead of the generic functions [4]. > > + /* Convert symbol name to UTF-8 */ > + utf8_len = WideCharToMultiByte(CP_UTF8, 0, symbol->Name, -1, > + NULL, 0, NULL, NULL); > + if (utf8_len > 0) > + { > + char *filename_utf8; > + int filename_len; > + > + utf8_buffer = palloc(utf8_len); > + WideCharToMultiByte(CP_UTF8, 0, symbol->Name, -1, > + utf8_buffer, utf8_len, NULL, NULL); > > + /* Convert symbol name to UTF-8 */ > + utf8_len = WideCharToMultiByte(CP_UTF8, 0, symbol->Name, -1, > + NULL, 0, NULL, NULL); > > You are calling WideCharToMultiByte twice. The reason is to allocate the exact > memory size. However, you can adopt another logic to avoid the first call. > > maxlen = symbol->NameLen * pg_database_encoding_max_length(); > symbol_name = palloc(maxlen + 1); > > (I suggest symbol_name instead of ut8_buffer.) > > You are considering only the UTF-8 case. Shouldn't it use wcstombs or > wcstombs_l? Maybe (re)use wchar2char -- see pg_locale_libc.c. > Hmm, you're probably right. I was thinking these Windows API strings needed special handling, but wchar2char should handle the conversion to database encoding correctly. Let me test that approach. > + if (filename_len > 0) > + { > + filename_utf8 = palloc(filename_len); > + WideCharToMultiByte(CP_UTF8, 0, line.FileName, -1, > + filename_utf8, filename_len, > + NULL, NULL); > + > + appendStringInfo(&errtrace, > + "\n%s+0x%llx [%s:%lu]", > + utf8_buffer, > + (unsigned long long) displacement, > + filename_utf8, > + (unsigned long) line.LineNumber); > + > + pfree(filename_utf8); > + } > + else > + { > + appendStringInfo(&errtrace, > + "\n%s+0x%llx [0x%llx]", > + utf8_buffer, > + (unsigned long long) displacement, > + (unsigned long long) address); > + } > > Maybe I missed something but is there a reason for not adding the address in the > first condition? > No particular reason. I was trying to keep it concise when we have file/ line info, but for consistency it probably should be there. Will send v5 with these fixes. > > [1] https://learn.microsoft.com/en-us/windows/win32/api/dbghelp/ns-dbghelp-symbol_infow > [2] https://www.postgresql.org/docs/current/error-style-guide.html > [3] https://learn.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-symfromaddrw > [4] https://learn.microsoft.com/en-us/windows/win32/intl/conventions-for-function-prototypes > > Thanks again for the review, Bryan