Uh oh!
There was an error while loading. Please reload this page.
Add format attribute to printf-style wrappers and fix format string errors - #123920
Conversation
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
jkotas
commented
Feb 3, 2026
Uh oh!
There was an error while loading. Please reload this page.
…, str) pattern Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 10 pipeline(s). 6 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 210 out of 210 changed files in this pull request and generated no new comments.
Suppressed comments (4)
src/coreclr/vm/peimagelayout.cpp:304
- This LOG call uses %p but passes GetPreferredBase()/GetBase() without casting to a pointer type. In this file these values are treated as pointer-sized integers (e.g., preferredBase = (void*)GetPreferredBase()), so this will trip format checking (and is UB). Cast to void* at the call site.
src/coreclr/debug/di/divalue.cpp:813 - Same as the constructor: the explicit "0x" prefix with %p will commonly result in "0x0x..." output. Drop the literal prefix here as well.
LOG((LF_CORDB,LL_EVERYTHING,"CRV::~CRV: this:0x%p\n",this));
src/coreclr/inc/stresslog.h:316
- StressLog::LogMsg stores varargs based on cArgs. LogMsgOL currently passes cArgs=0 but also passes one vararg ("%s", format), so the argument is not stored and later formatting of "%s" will read a missing argument (undefined behavior / corrupted stress log output).
src/coreclr/debug/di/divalue.cpp:744 - Using the literal prefix "0x" with %p will typically produce duplicated prefixes ("0x0x...") on platforms where %p already includes 0x. This file only has these two occurrences (constructor and destructor); consider dropping the explicit "0x" in both places for consistent output.
This issue also appears on line 813 of the same file.
LOG((LF_CORDB,LL_EVERYTHING,"CRV::CRV: this:0x%p\n",this));
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 210 out of 210 changed files in this pull request and generated no new comments.
Suppressed comments (2)
src/coreclr/vm/generics.cpp:724
- The new
%pformat specifiers now requirevoid*arguments underMINIPAL_ATTR_FORMAT_PRINTF; passingPTR_Module/MethodTable*directly will trigger format warnings (and defeats the goal of enabling compiler validation). Cast the pointer arguments tovoid*(usestatic_cast<void*>in C++).
src/coreclr/vm/methodtablebuilder.cpp:7096 - With
MINIPAL_ATTR_FORMAT_PRINTFenabled on logging helpers,%pexpects avoid*. PassingMethodDesc*directly will trigger format warnings. Cast the pointer tovoid*(preferstatic_cast<void*>in C++).
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 210 out of 210 changed files in this pull request and generated no new comments.
Suppressed comments (3)
src/coreclr/debug/di/divalue.cpp:813
- Same as above:
this:0x%pwill commonly log0x0x...because%palready includes the0xprefix on most platforms. Dropping the extra0xavoids noisy diagnostics.
LOG((LF_CORDB,LL_EVERYTHING,"CRV::~CRV: this:0x%p\n",this));
src/coreclr/gc/interface.cpp:749
- The dprintf format string uses
%zdformin_gen0_new_allocation/max_gen0_new_allocation, but those fields aresize_t(seegcpriv.h), so the correct specifier is%zu. With the new printf-format attributes this can produce warnings or UB on some platforms.
src/coreclr/debug/di/divalue.cpp:744 %ptypically already includes the0xprefix. Keepingthis:0x%pwill often log0x0x..., which is the exact issue this PR fixes elsewhere. Consider dropping the redundant0xprefix for pointer formatting.
This issue also appears on line 813 of the same file.
LOG((LF_CORDB,LL_EVERYTHING,"CRV::CRV: this:0x%p\n",this));
@copilot Replate all |
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Fixed all five Note This reply was generated by GitHub Copilot. |
jkoritzinsky
commented
Aug 14, 2026
/ba-g wasm deadletter unrelated |
Description
Enabled compiler validation of printf-style format strings by adding
__attribute__ ((format (printf, ...)))to wrapper functions. Fixed 85+ format string errors discovered by the compiler across CoreCLR, Mono, and Corehost. Merged with latest main branch to ensure compatibility with recent changes.Changes
Centralized format attribute macro in
src/native/minipal/types.h:MINIPAL_ATTR_FORMAT_PRINTF(fmt_pos, arg_pos)macro for consistent usage across the codebase#ifdef __GNUC__blocks throughout the codebaseAdded format attributes to 60+ wrapper functions across 13 headers using
MINIPAL_ATTR_FORMAT_PRINTF:src/native/minipal/types.h- CentralizedMINIPAL_ATTR_FORMAT_PRINTFmacro definitionsrc/native/minipal/log.h-minipal_log_printsrc/native/corehost/hostmisc/trace.h-trace::verbose,info,warning,error,printlnsrc/native/libs/Common/pal_compiler.h-do_abort_unlesssrc/native/libs/System.Native/pal_string.h-SystemNative_SNPrintFsrc/native/libs/System.Security.Cryptography.Native/osslcompat_30.h-ERR_set_error(uses sharedMINIPAL_ATTR_FORMAT_PRINTFmacro)src/coreclr/inc/log.h-LogSpew,LogSpew2,LogSpewAlwayssrc/coreclr/inc/stresslog.h-StressLog::LogMsg,ThreadStressLog::LogMsgsrc/coreclr/inc/sstring.h-Printf,AppendPrintfsrc/coreclr/jit/host.h-jitprintf,logf,flogf,gcDump_logfsrc/coreclr/jit/compiler.h-printfAlloc,JitLogEEsrc/coreclr/gc/gc.h-GCLogsrc/coreclr/gc/gcpriv.h-GCLogConfigsrc/mono/mono/eglib/glib.h-g_error_new,g_set_error,g_print,g_printerr,g_log,g_assertion_message,g_async_safe_*Fixed 85+ format string errors across 24 source files:
%I64d/%Id→%zd/%zuPRIX64/PRIx64/PRIu64from<inttypes.h>#and0flags(void*)cast for pointersprintf(str)→printf("%s", str)thisFiles with format errors fixed:
Added missing header includes:
src/coreclr/ildasm/ildasmpch.h- Added#include <inttypes.h>for PRI macrossrc/coreclr/tools/metainfo/mdinfo.cpp- Added#include <inttypes.h>for PRI macrossrc/coreclr/vm/jitinterface.cpp- Added#include <inttypes.h>for PRI macrossrc/coreclr/jit/gentree.cpp- Added#include <inttypes.h>for PRI macrosPortability for PRI macros in C++: Added guarded
__STDC_FORMAT_MACROSdefine before<inttypes.h>includes in C++ translation units that use PRI* format macros (emitwasm.cpp, jitinterface.cpp, stubgen.cpp, mdinfo.cpp, ildasmpch.h, arm64/loongarch64/riscv64 singlestepper.cpp). This keeps PRI macros visible on older C++ libc implementations (notably glibc) where they are gated behind__STDC_FORMAT_MACROSin C++ mode.Merged from main:
Review feedback addressed:
src/coreclr/vm/crst.cpp: Simplified format strings to avoid unnecessary line splitssrc/coreclr/gc/diagnostics.cpp: Removed unnecessary size_t casts (type already size_t)%zuinstead of%zdfor unsigned size_t%lldback to%dfor INT32 typeprintf("")calls withfflush(stdout)to fix GCCformat-zero-lengtherrors on linux.armel.Checkedsrc/coreclr/vm/gcheaputilities.cpp: Log invalid GC module name as UTF-8 string (MAKE_UTF8PTR_FROMWIDE+%s) instead of pointer (%p) so the diagnostic shows the actual namesrc/coreclr/jit/inlinepolicy.cpp: Printm_ModelCodeSizeEstimatefor thesize=label (the original code had a label/value mismatch where the per-call instruction estimate was being printed under thesizelabel)src/native/corehost/hostpolicy/hostpolicy_init.cpp: Changed%zd→%zuforsize_t input->version_loin two locationssrc/mono/mono/utils/mono-os-mutex.c: Castts.tv_sectolong longfor%lldandts.tv_nsectolongfor%ldin bothpthread_cond_timedwaitandpthread_cond_timedwait_relative_npbranchessrc/native/libs/System.Security.Cryptography.Native/osslcompat_30.h: Replaced inline#ifdef __GNUC__block onERR_set_errorwith the sharedMINIPAL_ATTR_FORMAT_PRINTFmacro and added#include <minipal/types.h>src/native/corehost/bundle/reader.h: Castint64_t m_offset_in_filetounsigned long longto match%llx(avoids varargs UB)src/coreclr/vm/stubgen.cpp: Use0x%zx/0x%08zxwith(size_t)cast forUINT_PTR pInstruction->uArgto fix Win64 truncation (whereunsigned longis 32-bit)src/coreclr/vm/threadsuspend.cpp:4312andsrc/coreclr/vm/amd64/excepamd64.cpp:197: Removed redundant0xliteral prefix before%pformat specifier (which already includes0xon most platforms, resulting in0x0x...output)src/coreclr/debug/di/rsthread.cpp:692: Added explicit(size_t)cast forUINT_PTR m_idused with%zxformat specifiersrc/tools/ilasm: Reverted accidental changes to auto-generated C# files that had introduced Windows-specific absolute paths into// Generated fromcommentsExample fixes:
Impact
#ifdef __GNUC__blocks via centralizedMINIPAL_ATTR_FORMAT_PRINTFmacro (now also used byosslcompat_30.h); restored original indentation to keep git history clean; reverted accidental changes to auto-generatedsrc/tools/ilasmfiles__STDC_FORMAT_MACROSbefore<inttypes.h>in C++ files for older libc compatibility; fixedUINT_PTRformatting in stubgen for Win64 (whereunsigned longis 32-bit); fixed builds across x64, ARM64, and 32-bit ARM platformsgcheaputilities.cpp(UTF-8 module name instead of pointer); fixed a pre-existing label/value mismatch ininlinepolicy.cppso thesize=log label now reports the model code size; removed redundant0xprefixes before%pspecifiers that were producing0x0x...output💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.