Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strconv.ParseInt: parsing "18446744073709551615": value out of range #401

Closed
gdejong opened this issue Jul 26, 2021 · 6 comments · Fixed by #402
Closed

strconv.ParseInt: parsing "18446744073709551615": value out of range #401

gdejong opened this issue Jul 26, 2021 · 6 comments · Fixed by #402

Comments

@gdejong
Copy link

gdejong commented Jul 26, 2021

After upgrading prometheus/procfs from 0.6.0 to 0.7.0 the process_cpu_seconds_total, process_virtual_memory_bytes and process_resident_memory_bytes metrics from prometheus/client_golang were no longer outputted.

We have a Go service running in a Docker container.

Using the ReportErrors option from ProcessCollectorOpts I was able to display the error.

prometheus.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{ReportErrors: true, Namespace: "test_"}))

Scraping the metrics gave:

An error has occurred while serving metrics:

strconv.ParseInt: parsing "18446744073709551615": value out of range

This is the maximum value of a uint64

The /proc/1/stat file contents:

# cat /proc/1/stat
1 (service) S 0 1 1 0 -1 1077944576 4345 0 1 0 13 17 0 0 20 0 5 0 346180303 732237824 2193 18446744073709551615 4194304 9876697 140737276107232 140737276105984 4665027 0 0 0 2143420159 18446744073709551615 0 0 17 4 0 0 1 0 0 14888960 15220704 24559616 140737276112712 140737276112721 140737276112721 140737276112879 0

This is parsed in proc_stat.go -> Stat()

The value 18446744073709551615 occurs twice. On position 23 and 33.
Position 33 is written into ignored which is defined as an int. A value as large as 18446744073709551615 cannot be read into an int datatype and this causes the error: strconv.ParseInt: parsing "18446744073709551615": value out of range

Possible solution: change the datatype of ignored from int to uint64?

image

@gdejong
Copy link
Author

gdejong commented Jul 26, 2021

Some extra information.

The /proc/<pid>/stat format is defined here: https://man7.org/linux/man-pages/man5/proc.5.html

All fields are listed there with their proper scanf format (https://man7.org/linux/man-pages/man3/scanf.3.html)

The 25th and 35th element are defined as:

              (25) rsslim  %lu
                     Current soft limit in bytes on the rss of the
                     process; see the description of RLIMIT_RSS in
                     getrlimit(2).
---

              (35) wchan  %lu  [PT]
                     This is the "channel" in which the process is
                     waiting.  It is the address of a location in the
                     kernel where the process is sleeping.  The
                     corresponding symbolic name can be found in
                     /proc/[pid]/wchan.

l - Indicates either that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a long or unsigned long (rather than int)
u - Matches an unsigned decimal integer; the next pointer must be a pointer to unsigned int.

So lu would become an unsigned long

This would lead me to assume that the proposed solution would be correct.

@vykulakov
Copy link
Contributor

Noticed the same issue with parsing /proc/[pid]/stat on some machines:

strconv.ParseInt: parsing \"18446744073709551615\": value out of range

It happened on parsing the following stat file:

29977 (test)  S 15396 29977 15396 34818  29977 1077944320 4995      0         0    0    77      241    0      0      20 0  24 0  3933239738 1603444736 2552  18446744073709551615 4194304 8586288  140734181603184 140734181602680 465270 7  0  1006254592 0  2143420159 18446744073709551615 0  0  17 17 0  0  0  0  0  12419072 12726432 42594304 140734181607380 140734181607391 140734181607391 140734181609453 0

The code that I used to build that test program is this (the last error check fires):

	pid := os.Getpid()
	proc, err := procfs.NewProc(pid)
	if err != nil {
		logrus.WithField("pid", pid).WithError(err).Error("cannot get proc for the current process")
		return
	}

	stat, err := proc.Stat()
	if err != nil {
		logrus.WithField("pid", pid).WithError(err).Error("cannot get proc stat for the current process")
		return
	}

The test program is run on the following kernel:

# uname -a
Linux example.com 3.10.0-1062.18.1.el7.x86_64 #1 SMP Tue Mar 17 23:49:17 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

On kernels with version 5.10 all works fine (what a relief).

@vykulakov
Copy link
Contributor

But we cannot just replace the int type for the ignored variable with the uint64 type because this variable is also used for the field 21:

              (21) itrealvalue  %ld

that means signed long. The code should have different ignored variables for different fields, I guess.

@vykulakov
Copy link
Contributor

I'll prepare PR.

@gdejong
Copy link
Author

gdejong commented Jul 27, 2021

I agree, multiple ignored variables with different datatypes would be appropriate.

@vykulakov
Copy link
Contributor

@gdejong thank you for the links right here.

Please, review the PR and maybe it will be merged soon. Thanks.

discordianfish pushed a commit that referenced this issue Jul 27, 2021
Some ignored fields in the /proc/[pid]/stat file may have values that are bigger than the max value of the current Go type that is used for the ignored variable. That leads to issues in runtime on some systems that use the maximum possible values for the related fields.

See for details:
* https://man7.org/linux/man-pages/man5/proc.5.html
* https://man7.org/linux/man-pages/man3/scanf.3.html

Signed-off-by: Vyacheslav Kulakov <kulakov.home@gmail.com>
remijouannet pushed a commit to remijouannet/procfs that referenced this issue Oct 20, 2022
Some ignored fields in the /proc/[pid]/stat file may have values that are bigger than the max value of the current Go type that is used for the ignored variable. That leads to issues in runtime on some systems that use the maximum possible values for the related fields.

See for details:
* https://man7.org/linux/man-pages/man5/proc.5.html
* https://man7.org/linux/man-pages/man3/scanf.3.html

Signed-off-by: Vyacheslav Kulakov <kulakov.home@gmail.com>
jritter pushed a commit to jritter/procfs that referenced this issue Jul 15, 2024
Some ignored fields in the /proc/[pid]/stat file may have values that are bigger than the max value of the current Go type that is used for the ignored variable. That leads to issues in runtime on some systems that use the maximum possible values for the related fields.

See for details:
* https://man7.org/linux/man-pages/man5/proc.5.html
* https://man7.org/linux/man-pages/man3/scanf.3.html

Signed-off-by: Vyacheslav Kulakov <kulakov.home@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants