README of the Y2038 cppcheck addon ================================== Contents 1. What is Y2038? 2. What is the Y2038 cppcheck 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 Unix 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 cppcheck 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: 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 have 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.