Skip to content

add git shortened sha1sum to CBMC version for unique id #668

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

Closed

Conversation

mgudemann
Copy link
Contributor

this adds the output of git describe --tags --always to the CBMC version string, making exact identification of a binary CBMC version possible.

@tautschnig
Copy link
Collaborator

I think this is a very good idea; yet I'd have a slightly different proposal lying around that I'd like to put forward for discussion. I'll post a link to a branch in a few minutes.

@mgudemann
Copy link
Contributor Author

I am curious to see this. Obviously my approach is not mergeable right away as it does not format nicely in the CBMC help() message, but having a UID would be beneficial in any case.

@tautschnig
Copy link
Collaborator

I have pushed tautschnig/cbmc@6694d4e - comments much appreciated.

@tautschnig
Copy link
Collaborator

@mgudemann I'll move the discussion in here if that's ok? Just to have the full trail in one place. Quoting yourself in the context of my use of git rev-parse --short HEAD:

@mgudemann said in tautschnig/cbmc@6694d4e:

For the overall version, I'd prefer the git describe --tags --always output, as it is a bit more extensive; as it will only show on --version this should be ok. But I have no strong feelings about this, in any case having n/a in case of a fail or +dirty is a very good idea.

Will the above work on windows? My proposal fails on Travis as git is not installed, I presume your version would work?

Quite frankly I wasn't aware of git describe --tags --always - it's indeed very nice and allows us to move that stanza I had placed in config.inc into common as there shouldn't be a need to change that anymore. All version setting is then sorted out via git tags.

The key difference between our approaches is the use of command-line defines vs generating a file. Can the file-base approach deal with uncommitted changes?

@mgudemann
Copy link
Contributor Author

git-describe even has a --dirty option which generates something like cbmc-5.6-847-g887c9c0-dirty for my current version (after an intentional uncommited change). If I am right, then this is tag+number of commits after last tag+short hash + (optional dirty flag)

@martin-cs
Copy link
Collaborator

martin-cs commented Mar 22, 2017 via email

@mgudemann
Copy link
Contributor Author

I think @tautschnig's solution is better, this together with git-describe and appropriate options should be enough to uniquely identify and also make local recompilation of an equivalent version possible.
We'd need to update the CI builds with git though, or at least have a fallback like n/a as in @tautschnig's approach

@tautschnig
Copy link
Collaborator

@mgudemann Would you mind doing the following, in an attempt to preserve the discussion: cherry-pick my commit into your branch for this pull request, possibly discard your commit, and add the suggested improvements such as using git describe --tags --always --dirty? Closing this pull request and opening a new one from my branch would be easy, but would lose the discussion.

@kroening
Copy link
Member

A luxury variant of this would recognise that a particular version is a release, and then mark it as such.

@tautschnig
Copy link
Collaborator

@kroening I believe we would actually get that via the proposed git describe: As an example, git describe --tags --always 8a0088e (the 5.6 tag) yields "cbmc-5.6", without any additional git revision.

@mgudemann mgudemann force-pushed the feature/git_version_output branch 3 times, most recently from 68d4ed6 to f8b3ab9 Compare March 23, 2017 10:59
@mgudemann
Copy link
Contributor Author

mgudemann commented Mar 23, 2017

@tautschnig I took your commit and adapted to current master
Windows uses different escaping, so the Makefiles now contain two definitions for CBMC_VERSION, using -DCBMC_VERSION=\"..\" and /DCBMC_VERSION='"""..."""''.

@kroening
Copy link
Member

The benefit of the earlier variant was that the build system would notice that a new version got checked out, and then re-build the files that include version.h.

Right now, that will only work when a manual 'make clean' is issued.

@tautschnig
Copy link
Collaborator

@kroening Isn't that only an issue when placing a tag? Any code changes would obviously trigger a rebuild and therefore the binaries would have the most up-to-date version information. If the only change is the version (but no files have been touched), then the only case where that can occur is when a tag has been placed. This seems to be a quarterly activity (at most), hence it might be acceptable to do touch */*parse_options.cpp (make clean isn't required).

@kroening
Copy link
Member

Yes, code changes would trigger a rebuild, but not necessarily to the file that prints the version number; i.e., you would get a binary that has a hash in that is inconsistent with the code that was compiled.

@tautschnig
Copy link
Collaborator

Ah, of course, apologies for missing that. There should actually be a setup such that a file is re-built whenever the version string changes. I'll think about a suitable make rule.

@mgudemann
Copy link
Contributor Author

how about

git_new_version: ../.git/HEAD ../.git/index
	touch git_new_version; touch */*parse_options.cpp

and adding git_new_version to the relevant build goals ?

@tautschnig
Copy link
Collaborator

@mgudemann My concern here is that it wouldn't update on a dirty code base!?

@forejtv
Copy link
Contributor

forejtv commented Mar 24, 2017

@martin-cs @mgudemann @kroening For identifying a version used by DiffBlue customers we use versioning from https://github.com/diffblue/platform/tree/develop/docker (private repo). The customers won't directly run cbmc from command line, so whatever approach is implemented here, they will not see it.

@tautschnig
Copy link
Collaborator

Here's how to make the version string update (not sure tabs paste well):

--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ src/goto-analyzer/taint_driver_scripts/.idea/*
 *.obj
 *.a
 *.lib
+.release_info
 src/ansi-c/arm_builtin_headers.inc
 src/ansi-c/clang_builtin_headers.inc
 src/ansi-c/cprover_library.inc
diff --git a/src/common b/src/common
index 20c4fad..fa290cb 100644
--- a/src/common
+++ b/src/common
@@ -182,12 +182,22 @@ OBJ += $(patsubst %.cc, %$(OBJEXT), $(filter %.cc, $(SRC)))
 %.obj:%.c
        $(CC) $(CP_CFLAGS) /nologo /c /EHsc $< /Fo$@

+KNOWN_RELEASE_INFO = $(shell cat .release_info 2>/dev/null)
+ifneq ($(RELEASE_INFO), $(KNOWN_RELEASE_INFO))
+$(filter %_parse_options$(OBJEXT), $(OBJ)): .release_info
+
+.release_info:
+       echo $(RELEASE_INFO) > $@
+
+.PHONY: .release_info
+endif
+
 clean:
        $(RM) $(patsubst %.cpp, %$(OBJEXT), $(filter %.cpp, $(SRC))) \
                $(patsubst %.cpp, %.d, $(filter %.cpp, $(SRC))) \
                $(patsubst %.cc, %$(OBJEXT), $(filter %.cc, $(SRC))) \
                $(patsubst %.cc, %.d, $(filter %.cc, $(SRC))) \
-               $(CLEANFILES)
+               $(CLEANFILES) .release_info

 .PHONY: first_target clean all
 .PHONY: sources generated_files

@mgudemann
Copy link
Contributor Author

mgudemann commented Mar 24, 2017

@tautschnig you could attach the patch, as zip if it doesn't work directly

@tautschnig
Copy link
Collaborator

I'm sorry, I should have done that before:
0001-Build-.release_info-files-containing-the-version-str.patch.zip

@martin-cs
Copy link
Collaborator

@forejtv There are two important use cases for this. One is me looking at logs to work out what is going wrong and being able to remotely replicate what is happening on customer sites -- they may not see it but I will. Second is for https://github.com/diffblue/test-gen/issues/187 . Both of these are causing pain in supporting customers so please could we remove the do not merge?

@tautschnig @mgudemann Can't this be done with simple keyword substitution in one file, like subversion would? Apparently https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Keyword-Expansion gives a recipe for this.

@tautschnig
Copy link
Collaborator

@forejtv I actually don't know why this is marked do-not-merge?

@martin-cs Thanks for the pointer to keyword substitution! Yet I'm not sure there's a genuine problem with the proposed solution? Note that keyword substitution won't cover the local-changes-in-repository problem, which the proposed patch does address.

@tautschnig
Copy link
Collaborator

I'll refrain from approving a PR that contains changes by myself ;-)

For regression tests, actually the keyword expansion might come into play: we could have a test that checks that the specific git commit id is included in the --version output.

@tautschnig tautschnig requested a review from forejtv May 8, 2017 16:21
@mgudemann
Copy link
Contributor Author

@tautschnig one thing I saw is this

* *   CBMC 5.7 (cbmc-5.7-243-gf7be1c4) - Copyright (C) 2001-2016 (64-bit version)   * *
* *              Daniel Kroening, Edmund Clarke             * *
* * Carnegie Mellon University, Computer Science Department * *
* *                 [email protected]                   * *
* *        Protected in part by U.S. patent 7,225,417       * *

maybe better have something like

* *   CBMC 5.7 - Copyright (C) 2001-2016 (64-bit version)   * *
* *                  (cbmc-5.7-243-gf7be1c4)                * *
* *              Daniel Kroening, Edmund Clarke             * *
* * Carnegie Mellon University, Computer Science Department * *
* *                 [email protected]                   * *
* *        Protected in part by U.S. patent 7,225,417       * *

@tautschnig
Copy link
Collaborator

Indeed; how about

* *       CBMC - Copyright (C) 2001-2016 (64-bit version)   * *
* *              (version cbmc-5.7-243-gf7be1c4)            * *
* *              Daniel Kroening, Edmund Clarke             * *
* * Carnegie Mellon University, Computer Science Department * *
* *                 [email protected]                   * *
* *        Protected in part by U.S. patent 7,225,417       * *

to make the implementation via CBMC_VERSION simpler?

@mgudemann
Copy link
Contributor Author

@tautschnig we have this now

* *   CBMC 5.7 - Copyright (C) 2001-2016 (64-bit version)   * *
* *                  (cbmc-5.7-244-g4df4a36)                * * 
* *              Daniel Kroening, Edmund Clarke             * *
* * Carnegie Mellon University, Computer Science Department * *
* *                 [email protected]                   * *
* *        Protected in part by U.S. patent 7,225,417       * *

@mgudemann
Copy link
Contributor Author

@forejtv I think this is becoming mergeable

Copy link
Contributor

@forejtv forejtv left a comment

Choose a reason for hiding this comment

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

I am not able to figure out how I should test this. When I check the branch out and compile, I don't see a git sha anywhere when I run cbmc, cbmc -help or cbmc --version, I am always just getting "5.7".

What should I be running to see the sha?

@tautschnig
Copy link
Collaborator

@forejtv That's rather surprising. I've just done this:

$ git remote add mgudemann https://github.com/mgudemann/cbmc
$ git fetch mgudemann
$ git checkout -t -b git_version_output mgudemann/git_version_output
$ make minisat2-download
$ make -j3
$ cbmc/cbmc --version
(cbmc-5.7-244-g4df4a36b8)

(And you should also see CBMC_VERSION being defined on the compiler command lines.)

@@ -53,6 +53,14 @@ CLEANFILES = cbmc$(EXEEXT)

all: cbmc$(EXEEXT)

ifeq ($(BUILD_ENV_),MSVC)
CP_CXXFLAGS += /DCBMC_TAG_VERSION='"""$(CBMC_VERSION)"""' \
/DCBMC_VERSION='"""($(GIT_INFO))"""'
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

@forejtv forejtv left a comment

Choose a reason for hiding this comment

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

When I delete the .git directory before compiling, as a result I get

CBMC version (n/a) 64-bit x86_64 linux

Is that expected? We're still keeping version info in https://github.com/diffblue/cbmc/pull/668/files/4df4a36b894fdf1f5fcfe4ad196505f2d334e36e#diff-b4a2f4e2f20572b496e8590dcf1dec51R33, so maybe that one should be used, with some suffix indicating that the version cannot be determined?

@forejtv
Copy link
Contributor

forejtv commented May 17, 2017

@tautschnig It worked for me on the next compilation attempt, I must have had a bad day.

@tautschnig
Copy link
Collaborator

Ok, good to know it worked. Your concerns are of course valid and need a solution.

@kroening
Copy link
Member

The key problem I see is that this requires a 'make clean' to make sure that all files that use the define get recompiled. Is there an intend to add dependencies on .release_info?

The key benefit of using an include is that the dependency system takes care of incremental builds. Thus, I'd suggest:

  1. The make files write the git hash into some header file IF it has changed.
  2. The .cpp files include that header file to get the version string.

@tautschnig
Copy link
Collaborator

The dependencies are addressed via changes to common - and it would be possible to use the .release_info files for grabbing the version string.

@tautschnig tautschnig changed the base branch from master to develop August 22, 2017 12:32
@tautschnig
Copy link
Collaborator

@mgudemann Any chance to push this further?

@tautschnig
Copy link
Collaborator

@mgudemann Is there any chance you might be able to progress this PR? Do let me know if you'd like to hand off this PR to someone else. I'm repeatedly running into the issue that people have results with some version of CBMC and we then cannot figure out what exact source version that had been compiled from.

@martin-cs
Copy link
Collaborator

+1 would love to see this functionality merged.

@chrisr-diffblue
Copy link
Contributor

+1 would love to see this too.

@tautschnig
Copy link
Collaborator

I'm happy to create a new PR to drive this myself, but I don't want to do what could be seen as a hostile takeover as @mgudemann hasn't commented on this.

@mgudemann
Copy link
Contributor Author

@tautschnig I am happy with you taking this over. For TG we have a cmake solution, we should keep that in mind when adding that to CBMC / JBMC.

@tautschnig
Copy link
Collaborator

Taking over work on this in #2373.

@tautschnig tautschnig closed this Jun 20, 2018
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.

6 participants