View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0013106CMakeCMakepublic2012-04-06 05:032013-01-09 14:05
Reportertfischer 
Assigned ToDavid Cole 
PrioritynormalSeverityminorReproducibilityrandom
StatusclosedResolutionno change required 
PlatformGentoo LinuxOSLinuxOS Version
Product VersionCMake 2.8.6 
Target VersionCMake 2.8.10Fixed in VersionCMake 2.8.10 
Summary0013106: SystemTools::CopyFileAlways fails at random due to invalid kwsys_ios::ifstream fin
DescriptionI am using a custom cmake script to determine the SVN revision number of my source code during build time and to write this version number into a file "version.h" so that the compiler can include the version string into the compiled code.
The script works as follows: First, it determines the SVN revision (svnversion or environment variable) and writes a small header file called version.h.tmp. To avoid unnecessary recompilations, cmake's copy_if_different is used to copy version.h.tmp to version.h only if the SVN revision (therefore the file's content) has changed.

When testing the script, in irregular intervals the copy_if_different call fails with error message:
Error copying file (if different) from "/home/tf/programming/gna/qtcreator-build/src/parts/version.h.tmp" to "/home/tf/programming/gna/qtcreator-build/src/parts/version.h".
I added print statements before each "return false" statement in SystemTools::CopyFileAlways (eventually called by copy_if_different) to check which test fails. As it turns out, the test for !fin fails in line 1849 (for CMake 2.8.6).

The problem now is, that this failure does not follow any pattern as far as I can see. Running my custom script (attached to this report) 20 times in a loop (bash for-loop), the following output is generated.

-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
kwsys_ios::ifstream fin is NULL
Error copying file (if different) from "/home/tf/programming/gna/qtcreator-build/src/parts/version.h.tmp" to "/home/tf/programming/gna/qtcreator-build/src/parts/version.h".
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
kwsys_ios::ifstream fin is NULL
Error copying file (if different) from "/home/tf/programming/gna/qtcreator-build/src/parts/version.h.tmp" to "/home/tf/programming/gna/qtcreator-build/src/parts/version.h".
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
-- SVN version was set outside through environment variable SVN_REV
-- SVN version is AAA
kwsys_ios::ifstream fin is NULL
Error copying file (if different) from "/home/tf/programming/gna/qtcreator-build/src/parts/version.h.tmp" to "/home/tf/programming/gna/qtcreator-build/src/parts/version.h".

The for-loop to call this script is:
for n in {1..20} ; do /usr/bin/cmake -DSOURCE_DIR=/home/tf/programming/gna/proj/src/parts -DBINARY_DIR=/home/tf/programming/gna/qtcreator-build/src/parts -P /home/tf/programming/gna/proj/src/getsvn.cmake ; done

Any ideas what could cause this behaviour? How to debug/trace this problem?
TagsNo tags attached.
Attached Files? file icon getsvn.cmake [^] (2,630 bytes) 2012-04-06 05:03
? file icon race.cmake [^] (815 bytes) 2012-08-22 16:11

 Relationships

  Notes
(0030389)
David Cole (manager)
2012-08-11 21:35

Sending old, never assigned issues to the backlog.

(The age of the bug, plus the fact that it's never been assigned to anyone means that nobody is actively working on it...)

If an issue you care about is sent to the backlog when you feel it should have been addressed in a different manner, please bring it up on the CMake mailing list for discussion. Sign up for the mailing list here, if you're not already on it: http://www.cmake.org/mailman/listinfo/cmake [^]

It's easy to re-activate a bug here if you can find a CMake developer who has the bandwidth to take it on, and ferry a fix through to our 'next' branch for dashboard testing.
(0030738)
tfischer (reporter)
2012-08-22 16:11

I was able to trace this problem further. It seems that it makes a difference if "copy_if_different" and "remove" are executed in the same "execute_process" or in two different "execute_process" statements.
I haven't checked that in the sources, but my guess would be that the two command statements inside the execute_process statement are executed in parallel (resulting in a race condition as observed) contrary to the documentation which states "Runs the given sequence of one or more commands ..." (emphasis on "sequence", i.e. sequential, which is not parallel).

Please have a look on the attached example script and try to confirm my observation.
(0030741)
David Cole (manager)
2012-08-22 16:32

You are observing behavior that is by design. Sorry nobody took a closer look at this issue and got back to you before now.

The documentation for execute_process clearly states "Runs the given sequence of one or more commands with the standard output of each process piped to the standard input of the next."

The standard output of cmd1 is *PIPED* into the stdin of cmd2, so of course they're both going to be running at the same time.

It's as if you did this in a command prompt:

  cmake -E copy_if_different f1 f2 | cmake -E remove f1

You are probably thinking that it's as if you used "&&" instead of "|" in the command prompt...

So... your solution is easy. Please use two separate execute_process commands.

Perhaps the documentation should be rephrased to avoid the word sequence, since the commands will run simultaneously as they produce and consume output/input. But other than using the word "sequence" in the documentation, there's no issue here. This is behaving the way it is intended.
(0032079)
Robert Maynard (manager)
2013-01-09 14:05

Closing resolved issues that have not been updated in more than 4 months.

 Issue History
Date Modified Username Field Change
2012-04-06 05:03 tfischer New Issue
2012-04-06 05:03 tfischer File Added: getsvn.cmake
2012-08-11 21:35 David Cole Status new => backlog
2012-08-11 21:35 David Cole Note Added: 0030389
2012-08-22 16:11 tfischer Note Added: 0030738
2012-08-22 16:11 tfischer File Added: race.cmake
2012-08-22 16:27 David Cole Assigned To => David Cole
2012-08-22 16:27 David Cole Status backlog => assigned
2012-08-22 16:32 David Cole Note Added: 0030741
2012-08-22 16:32 David Cole Status assigned => resolved
2012-08-22 16:32 David Cole Fixed in Version => CMake 2.8.10
2012-08-22 16:32 David Cole Resolution open => no change required
2012-08-22 16:32 David Cole Target Version => CMake 2.8.10
2013-01-09 14:05 Robert Maynard Note Added: 0032079
2013-01-09 14:05 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team