Skip to content

Conversation

@tommcdon
Copy link
Member

@tommcdon tommcdon commented Dec 8, 2025

Fix a recent regression in perfmaps caused by #116203
The fix changes fprintf usage in PerfMap::WriteLine to using

@tommcdon tommcdon added this to the 10.0.x milestone Dec 8, 2025
@tommcdon tommcdon requested a review from a team December 8, 2025 01:19
@tommcdon tommcdon self-assigned this Dec 8, 2025
Copilot AI review requested due to automatic review settings December 8, 2025 01:19
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @steveisok, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a regression in perfmap output caused by incorrect error checking in fprintf usage. The previous code treated successful writes as errors due to checking if the return value was not equal to zero, when fprintf actually returns the number of characters written (> 0) on success.

Key Changes

  • Replaced fprintf(m_fp, "%s", line.GetUTF8()) with a direct write() system call using the file descriptor
  • Fixed error checking to properly detect write failures and partial writes

{
// Write the line.

if (fprintf(m_fp, "%s", line.GetUTF8()) != 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the problem with fprintf?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bug was introduced by comparing the output of fprintf to 0. fprintf returns a value < 0 on failure, otherwise the number of bytes written to the stream.
Since we always use a formatting character of "%s", we can use write to accomplish the same task.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be valuable to double check the return value handling of each stdio function. Some returns error code and some returns meaningful length.

Since we always use a formatting character of "%s", we can use write to accomplish the same task.

Or maybe fwrite to be consistent at stdio level?

@jkotas
Copy link
Member

jkotas commented Dec 8, 2025

cc @huoyaoyuan

@jkotas
Copy link
Member

jkotas commented Dec 8, 2025

Fix a recent regression in perfmaps caused by #116203
tommcdon added this to the 10.0.x milestone

#116203 was merge 3 weeks ago. It is not in .NET 10.

@tommcdon
Copy link
Member Author

tommcdon commented Dec 8, 2025

Fix a recent regression in perfmaps caused by #116203
tommcdon added this to the 10.0.x milestone

#116203 was merge 3 weeks ago. It is not in .NET 10.

Setting the milestone to 10.0 was an error on my part. The intent was to fix this in main only.

int fd = fileno(m_fp);
const char* buf = line.GetUTF8();
size_t len = line.GetCount();
ssize_t written = write(fd, buf, len);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • FILE does buffering for better perf. Using write sys-call directly is going to be slower. Would it be better to use fwrite to benefit from the buffering?
  • If we want to use direct sycallls for some reason, the syscalls should be wrapped in EINTR dance like
    while ((bytesWritten = write(outFd, buffer + offset, (size_t)bytesRead)) < 0 && errno == EINTR);
    . Also, we can open/close the flle using open/close syscalls and avoid using FILE.

// Write the line.

if (fprintf(m_fp, "%s", line.GetUTF8()) != 0)
if (fprintf(m_fp, "%s", line.GetUTF8()) != line.GetCount())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SString::GetCount is going to convert the string to Unicode and return the number of unicode characters:

ConvertToFixed();
SS_RETURN SizeToCount(GetSize());
. SString is not very intuitive...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants