cppcheck/addons/y2038
Ayaz Salikhov 2dd6168258 Improve Python code 2017-06-04 22:51:48 +02:00
..
test Update Y2038 addon 2016-06-29 11:25:11 +02:00
README Fix some typos in comments (found by codespell) 2016-11-27 11:40:42 +01:00
y2038.py Improve Python code 2017-06-04 22:51:48 +02:00

README

README of the Y2038 cppcheck addon
==================================

Contents

1. What is Y2038?
2. What is the Y2038 ccpcheck addon?
3. How does the Y2038 cppcheck addon work?
4. How to use the Y2038 cppcheck addon

---

1. What is Y2038?

In a few words:

In Linux, the current date and time is kept as the number of seconds elapsed
since the Unich epoch, that is, since January 1st, 1970 at 00:00:00 GMT.

Most of the time, this representation is stored as a 32-bit signed quantity.

On January 19th, 2038 at 03:14:07 GMT, such 32-bit representations will reach
their maximum positive value.

What happens then is unpredictable: system time might roll back to December
13th, 1901 at 19:55:13, or it might keep running on until February 7th, 2106
at 06:28:15 GMT, or the computer may freeze, or just about anything you can
think of, plus a few ones you can't.

The workaround for this is to switch to a 64-bit signed representation of time
as seconds from the Unix epoch. This representation will work for more than 250
billion years.

Working around Y2038 requires fixing the Linux kernel, the C libraries, and
any user code around which uses 32-bit epoch representations.

There is Y2038-proofing work in progress on the Linux and GNU glibc front.

2. What is the Y2038 ccpcheck addon?

The Y2038 cppcheck addon is a tool to help detect code which might need fixing
because it is Y2038-unsafe. This may be because it uses types or functions from
GNU libc or from the Linux kernel which are known not to be Y2038-proof.

3. How does the Y2038 cppcheck addon work?

The Y2038 cppcheck addon takes XML dumps produced by cppcheck from source code
files and looks for the names of types or functions which are known to be Y2038-
unsafe, and emits diagnostics whenever it finds one.

Of course, this is of little use if your code uses a Y2038-proof glibc and
correctly configured Y2038-proof time support.

This is why y2038.py takes into account two preprocessor directives:
_TIME_BITS and __USE_TIME_BITS64.

_TIME_BITS is defined equal to 64 by user code when it wants 64-bit time
support from the GNU glibc. Code which does not define _TIME_BITS equal to 64
(or defines it to something else than 64) runs a risk of not being Y2038-proof.

__USE_TIME_BITS64 is defined by the GNU glibc when it actually provides 64-bit
time support. When this is defined, then all glibc symbols, barring bugs, are
Y2038-proof (but your code might have its own Y2038 bugs, if it handles signed
32-bit Unix epoch values).

The Y2038 cppcheck performs the following checks:

  1. Upon meeting a definition for _TIME_BITS, if that definition does not
     set it equal to 64, this error diagnostic is emitted:

	Error: _TIME_BITS must be defined equal to 64

     This case is very unlikely but might result from a typo, so pointing
     it out is quite useful. Note that definitions of _TIME_BITS as an
     expression evaluating to 64 will be flagged too.

  2. Upon meeting a definition for _USE_TIME_BITS64, if _TIME_BITS is not
     defined equal to 64, this information diagnostic is emitted:

	Warning: _USE_TIME_BITS64 is defined but _TIME_BITS was not

     This reflects the fact that even though the glibc checked default to
     64-bit time support, this was not requested by the user code, and
     therefore the user code might fail Y2038 if built against a glibc
     which defaults to 32-bit time support.

  3. Upon meeting a symbol (type or function) which is known to be Y2038-
     unsafe, if _USE_TIME_BITS64 is undefined or _TIME_BITS not properly
     defined, this warning diagnostic is emitted:

	Warning: <symbol> is Y2038-unsafe

     This reflects the fact that the user code is referring to a symbol
     which, when glibc defaults to 32-bit time support, might fail Y2038.

General note: y2038.py will handle multiple configurations, and will
emit diagnostics for each configuration in turn.

4. How to use the Y2038 cppcheck addon

The Y2038 cppcheck addon is used like any other cppcheck addon:

	cppcheck --dump file1.c [ file2.c [...]]]
	y2038.py file1.c [ file2.c [...]]]

Sample test C file is provided:

	test/y2038-test-1-bad-time-bits.c
	test/y2038-test-2-no-time-bits.c
	test/y2038-test-3-no-use-time-bits.c
	test/y2038-test-4-good.c

These cover the cases described above. You can run them through cppcheck
and y2038.py to see for yourself how the addon diagnostics look like. If
this README is not outdated (and if it is, feel free to submit a patch),
you can run cppcheck on these files as on any others:

	cppcheck --dump addons/y2038/test/y2038-*.c
	y2038.py addons/y2038/test/y2038-*.dump

If you havve not installed cppcheck yet, you will have to run these
commands from the root of the cppcheck repository:

    make
    sudo make install
	./cppcheck --dump addons/y2038/test/y2038-*.c
    PYTHONPATH=addons python addons/y2038/y2038.py addons/y2038/test/y2038-*.c.dump

In both cases, y2038.py execution should result in the following:

Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump...
Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump, config ""...
Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump...
Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump, config ""...
Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump...
Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump, config ""...
Checking addons/y2038/test/y2038-test-4-good.c.dump...
Checking addons/y2038/test/y2038-test-4-good.c.dump, config ""...
# Configuration "":
# Configuration "":
[addons/y2038/test/y2038-test-1-bad-time-bits.c:8]: (error) _TIME_BITS must be defined equal to 64
[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not
[addons/y2038/test/y2038-test-1-bad-time-bits.c:10]: (information) addons/y2038/test/y2038-inc.h was included from here
[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not
[addons/y2038/test/y2038-test-2-no-time-bits.c:8]: (information) addons/y2038/test/y2038-inc.h was included from here
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:13]: (warning) timespec is Y2038-unsafe
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:15]: (warning) clock_gettime is Y2038-unsafe

Note: y2038.py recognizes option --template as cppcheck does, including
pre-defined templates 'gcc', 'vs' and 'edit'. The short form -t is also
recognized.