Add format attribute to printf-style wrappers and fix format string errors#123920
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>
…, str) pattern Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
|
@copilot fix this build break and the "should fix" sections of #123920 (comment) |
... I've checked the current state:
The referenced comment #4203692711 content appears truncated. Could you provide:
This will help me identify and fix the exact issues. |
|
@copilot here's the "should fix" parts of the review:
|
…om code review Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/c6d266c3-2575-4a12-a8e5-4dcbad30990f Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
... Fixed in commit 4f7b7ef: Indentation changes restored:
Format/cast mismatches fixed:
Blank lines removed:
|
|
@copilot here's more build failures to fix: |
... The error message appears truncated. Could you provide the complete compiler error from gentree.cpp? I need to see the specific format string error to fix it properly. In the meantime, I'll search for format string issues in gentree.cpp to identify potential problems. |
| enable_no_gc_region_callback_status gc_heap::enable_no_gc_callback(NoGCRegionCallbackFinalizerWorkItem* callback, uint64_t callback_threshold) | ||
| { | ||
| dprintf(1, ("[no_gc_callback] calling enable_no_gc_callback with callback_threshold = %llu\n", callback_threshold)); | ||
| dprintf(1, ("[no_gc_callback] calling enable_no_gc_callback with callback_threshold = %lu\n", callback_threshold)); | ||
| enable_no_gc_region_callback_status status = enable_no_gc_region_callback_status::succeed; |
There was a problem hiding this comment.
callback_threshold is a uint64_t, but it is logged with %lu here. On LLP64 platforms (Windows), unsigned long is 32-bit, so this truncates the value and (with the new format checking) can trigger a format/type warning. Use PRIu64 (or %llu with an explicit cast to unsigned long long) for this argument.
| if (dd_new_allocation (hp->dynamic_data_of (soh_gen0)) <= (ptrdiff_t)soh_withheld_budget) | ||
| { | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of soh budget= %llu\n", soh_withheld_budget)); | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of soh budget= %lu\n", soh_withheld_budget)); | ||
| status = insufficient_budget; | ||
| } | ||
| if (dd_new_allocation (hp->dynamic_data_of (loh_generation)) <= (ptrdiff_t)loh_withheld_budget) | ||
| { | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of loh budget= %llu\n", loh_withheld_budget)); | ||
| dprintf(1, ("[no_gc_callback] failed because of running out of loh budget= %lu\n", loh_withheld_budget)); | ||
| status = insufficient_budget; |
There was a problem hiding this comment.
soh_withheld_budget/loh_withheld_budget are size_t but are logged with %lu. This is not portable (on Windows size_t is 64-bit but unsigned long is 32-bit) and will also be flagged by the new printf format validation. Use %zu (or cast to an appropriately sized unsigned type) for these values.
| LOG((LF_GC, level, " Handles Scanned = %llu\n", pTable->_DEBUG_TotalHandlesActuallyScanned [i])); | ||
| LOG((LF_GC, level, " Blocks Examined = %ld\n", pTable->_DEBUG_TotalBlocksScannedNonTrivially[i])); | ||
| LOG((LF_GC, level, " Slots Scanned = %ld\n", pTable->_DEBUG_TotalHandleSlotsScanned [i])); | ||
| LOG((LF_GC, level, " Handles Scanned = %ld\n", pTable->_DEBUG_TotalHandlesActuallyScanned [i])); |
There was a problem hiding this comment.
totalBlocksScanned is declared as int64_t, but is printed using %ld (and the related per-generation counters are printed with %ld too). On Windows long is 32-bit, so this truncates and is a format/type mismatch under printf checking. Use PRId64/PRIi64 (or %lld with casts to long long) consistently for these 64-bit counters.
| uint64_t elapsed = GetHighPrecisionTimeStamp () - start_us; | ||
|
|
||
| dprintf (8888, ("rethreaded %Id items, merging took %I64dus (%I64dms)", | ||
| dprintf (8888, ("rethreaded %zd items, merging took %ldus (%ldms)", | ||
| total_num_fl_items_rethreaded_stage2, elapsed, (elapsed / 1000))); |
There was a problem hiding this comment.
elapsed is a uint64_t, but the log uses %ldus/%ldms. This is non-portable (Windows long is 32-bit) and will be flagged by printf format validation. Prefer PRIu64 (or %llu with casts) for the timestamp and derived values.
| dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[dynamic_heap_count_data.sample_index]; | ||
| wait_time = min (wait_time, (uint32_t)(sample.elapsed_between_gcs / 1000 / 3)); | ||
| wait_time = max (wait_time, 1u); | ||
|
|
||
| dprintf (6666, ("gc#0 thread waiting for %d ms (betwen GCs %I64d)", wait_time, sample.elapsed_between_gcs)); | ||
| dprintf (6666, ("gc#0 thread waiting for %d ms (betwen GCs %ld)", wait_time, sample.elapsed_between_gcs)); | ||
| } |
There was a problem hiding this comment.
sample.elapsed_between_gcs is a uint64_t (see dynamic_heap_count_data_t::sample in gcpriv.h), but is logged here with %ld. This truncates on LLP64 and is a format/type mismatch with the new printf validation. Use PRIu64 (or %llu with cast to unsigned long long) when printing this value.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- jitinterface.cpp: Fix INT64 delta with %08x -> %08" PRIx64 " with (uint64_t) cast - ceeload.cpp: Fix size_t args with %lx -> %zx - arm64/singlestepper.cpp: Fix uint64_t values with %lx -> %" PRIx64 " (5 LOG calls) - loongarch64/singlestepper.cpp: Same fixes as arm64 (5 LOG calls) - riscv64/singlestepper.cpp: Same fixes as arm64 (5 LOG calls) Added #include <inttypes.h> where needed for PRIx64 macro. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace non-portable format specifiers (%ld, %lu) with portable alternatives using <inttypes.h> macros: - uint64_t: use PRIu64 macro via string concatenation - int64_t: use PRId64 macro via string concatenation - size_t: use %zu (unsigned) Files fixed: dynamic_heap_count.cpp, collect.cpp, init.cpp, no_gc.cpp, plan_phase.cpp, handletable.cpp, allocation.cpp Added #include <inttypes.h> to env/common.h (standalone GC build), gcpriv.h (coreclr VM build), and handletable.cpp (standalone compilation). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Annotate log_init_error_to_host, LogErrorToHost, _MulticoreJitTrace, FormatString, CrashInfo::Trace, CrashInfo::TraceVerbose, trace_printf, trace_verbose_printf, printf_status, and printf_error with MINIPAL_ATTR_FORMAT_PRINTF so the compiler checks format strings. Fix format mismatches found by the new annotations: - crashinfomac.cpp: cast pages_resident to unsigned long long for %llx; use %zd/%lu for size_t/ssize_t/vm_size_t args - createdumpmain.cpp: use PRIu64 for uint64_t g_ticksPerMS and elapsed - createdumpunix.cpp: use %lu cast for PAGE_SIZE (vm_size_t) - dumpwritermacho.cpp: use %zu for size_t; use PRIu64 for uint64_t - interface.cpp: use %.3f for float ratio values in log_init_error_to_host Also fix pre-existing broken string literals in collect.cpp and dynamic_heap_count.cpp where trailing commas were inside the format string instead of separating it from arguments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…subsystems Fix format specifier/argument type mismatches caught by __attribute__((format)): GC: Fix %zd with uint64_t in card_table.cpp, dynamic_heap_count.cpp, dynamic_tuning.cpp, gc.cpp, init.cpp, mark_phase.cpp VM: Fix %p with PCODE/TADDR in arm64/stubs.cpp, %S with LPCWSTR in cdacstress.cpp, %p with PCODE in multicorejitplayer.cpp, MAKE_UTF8PTR_FROMWIDE for wide string in multicorejitplayer.cpp JIT: Fix %ld with INT64 in valuenum.cpp Debug: Fix %zx with ULONG_PTR/CORDB_ADDRESS in debug/di/ files, %zx with PRD_TYPE in controller.cpp/executioncontrol.cpp, %p with PCODE/TADDR in arm64/walker.cpp, %x with DT_CONTEXT*/SIZE_T in shared/arm64/primitives.cpp Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tribute-to-wrappers # Conflicts: # src/coreclr/debug/di/process.cpp # src/coreclr/debug/di/rsthread.cpp # src/coreclr/debug/ee/debugger.cpp # src/coreclr/debug/ee/debugger.inl # src/coreclr/debug/ee/debuggermodule.cpp # src/coreclr/jit/lower.cpp # src/coreclr/vm/dllimport.cpp
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_errorsrc/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 macrosMerged 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 typeExample fixes:
Impact
#ifdef __GNUC__blocks via centralizedMINIPAL_ATTR_FORMAT_PRINTFmacro; restored original indentation to keep git history clean💡 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.