pacemaker icon indicating copy to clipboard operation
pacemaker copied to clipboard

RFC: Build: Add support for generating cflow reports for cmdline tools.

Open clumens opened this issue 2 years ago • 2 comments

cflow is a program that generates reports of function call chains in C source files. I find it most useful in determining where a function I want to get rid of is getting called, though it could be used for a bunch of other things.

It's really most useful if you give it a function. Otherwise, it will generate all possible call chains, which is very large. Pass the function you're interested in (and any other extra arguments) via the CFLOW_FLAGS environment variable.

For instance, if you want to see everwhere that calls crm_perror:

$ make -C tools CFLOW_FLAGS="--target crm_perror" cflow

Or, you can see everything that a single function calls:

$ make -C tools CFLOW_FLAGS="--main pcmk__add_mainloop_ipc" cflow

However note that in this case, the per-tool output makes less sense. You'll probably just end up with a bunch of duplicate copies of a single report.

Additionally, if you're only interested in generating a report for a single command line tool, you can do this:

$ make -C tools CFLOW_FLAGS="--target crm_perror" crm_rule.cflow

Other things to note:

  • You do not need to build the source before running this.

  • It will output a lot of warnings about redefinitions, which I think is mostly due to reusing argument names and things like that. It doesn't seem to be causing problems.

  • I have purposefully not added any -Idir include arguments to the call to cflow. It will take these, but it doesn't seem to do much for us at the moment besides slow everything way down.

clumens avatar Aug 22 '23 16:08 clumens

And here's some example output. It can be pretty redundant, but the good news is that means things clean up really fast when you deal with a single call:

+-main() <int () at crm_rule.c:99>
  +-pcmk__cli_init_logging() <void () at ../lib/common/logging.c:1117>
  | \-crm_log_init() <gboolean () at ../lib/common/logging.c:876>
  |   +-crm_perror()
  |   \-mainloop_add_signal() <gboolean () at ../lib/common/mainloop.c:357>
  |     \-crm_perror()
  \-pcmk__check_rules() <int () at ../lib/pacemaker/pcmk_rule.c:245>
    \-init_rule_check() <int () at ../lib/pacemaker/pcmk_rule.c:61>
      \-cib__signon_query() <int () at ../lib/cib/cib_utils.c:911>
        \-cib_new() <cib_t * () at ../lib/cib/cib_client.c:598>
          +-cib_shadow_new() <cib_t * () at ../lib/cib/cib_client.c:540>
          | +-get_shadow_file() <char * () at ../lib/cib/cib_client.c:480>
          | | \-crm_perror()
          | \-cib_file_new() <cib_t * () at ../lib/cib/cib_file.c:654>
          |   +-cib_file_perform_op_delegate() <int () at ../lib/cib/cib_file.c:295>
          |   | \-cib_file_process_request() <int () at ../lib/cib/cib_file.c:214>
          |   |   +-cib_perform_op() <int () at ../lib/cib/cib_utils.c:193>
          |   |   | +-patchset_process_digest() <void () at ../lib/common/patchset.c:377>
          |   |   | | \-calculate_xml_versioned_digest() <char * () at ../lib/common/digest.c:167>
          |   |   | |   \-calculate_xml_digest_v2() <char * () at ../lib/common/digest.c:92>
          |   |   | |     \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
          |   |   | |       \-write_xml_file() <int () at ../lib/common/xml.c:1283>
          |   |   | |         \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |   |   | |           \-crm_perror()
          |   |   | +-xml_apply_patchset() <int () at ../lib/common/patchset.c:1092>
          |   |   | | +-calculate_xml_versioned_digest() <char * () at ../lib/common/digest.c:167>
          |   |   | | | \-calculate_xml_digest_v2() <char * () at ../lib/common/digest.c:92>
          |   |   | | |   \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
          |   |   | | |     \-write_xml_file() <int () at ../lib/common/xml.c:1283>
          |   |   | | |       \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |   |   | | |         \-crm_perror()
          |   |   | | \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
          |   |   | |   \-write_xml_file() <int () at ../lib/common/xml.c:1283>
          |   |   | |     \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |   |   | |       \-crm_perror()
          |   |   | \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
          |   |   |   \-write_xml_file() <int () at ../lib/common/xml.c:1283>
          |   |   |     \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |   |   |       \-crm_perror()
          |   |   \-validate_xml_verbose() <gboolean () at ../lib/common/schemas.c:676>
          |   |     +-write_xml_fd() <int () at ../lib/common/xml.c:1255>
          |   |     | \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |   |     |   \-crm_perror()
          |   |     \-dump_file() <void () at ../lib/common/schemas.c:645>
          |   |       \-crm_perror()
          |   +-cib_file_signon() <int () at ../lib/cib/cib_file.c:420>
          |   | \-load_file_cib() <int () at ../lib/cib/cib_file.c:384>
          |   |   \-filename2xml() <xmlNode * () at ../lib/common/xml.c:990>
          |   |     \-decompress_file() <char * () at ../lib/common/xml.c:901>
          |   |       \-crm_perror()
          |   +-cib_file_signoff() <int () at ../lib/cib/cib_file.c:537>
          |   | +-cib_file_write_live() <int () at ../lib/cib/cib_file.c:455>
          |   | | +-crm_perror()
          |   | | \-cib_file_write_with_digest() <int () at ../lib/cib/cib_file.c:926>
          |   | |   +-cib_file_read_and_verify() <int () at ../lib/cib/cib_file.c:752>
          |   | |   | +-crm_perror()
          |   | |   | +-filename2xml() <xmlNode * () at ../lib/common/xml.c:990>
          |   | |   | | \-decompress_file() <char * () at ../lib/common/xml.c:901>
          |   | |   | |   \-crm_perror()
          |   | |   | \-cib_file_verify_digest() <gboolean () at ../lib/cib/cib_file.c:710>
          |   | |   |   \-pcmk__verify_digest() <bool () at ../lib/common/digest.c:202>
          |   | |   |     \-crm_perror()
          |   | |   +-cib_file_backup() <int () at ../lib/cib/cib_file.c:812>
          |   | |   | +-crm_perror()
          |   | |   | +-pcmk__write_series_sequence() <void () at ../lib/common/io.c:187>
          |   | |   | | \-crm_perror()
          |   | |   | \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
          |   | |   |   \-crm_perror()
          |   | |   +-crm_perror()
          |   | |   +-write_xml_fd() <int () at ../lib/common/xml.c:1255>
          |   | |   | \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |   | |   |   \-crm_perror()
          |   | |   \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
          |   | |     \-crm_perror()
          |   | \-write_xml_file() <int () at ../lib/common/xml.c:1283>
          |   |   \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |   |     \-crm_perror()
          |   \-cib_file_free() <int () at ../lib/cib/cib_file.c:582>
          |     \-cib_file_signoff() <int () at ../lib/cib/cib_file.c:537>
          |       +-cib_file_write_live() <int () at ../lib/cib/cib_file.c:455>
          |       | +-crm_perror()
          |       | \-cib_file_write_with_digest() <int () at ../lib/cib/cib_file.c:926>
          |       |   +-cib_file_read_and_verify() <int () at ../lib/cib/cib_file.c:752>
          |       |   | +-crm_perror()
          |       |   | +-filename2xml() <xmlNode * () at ../lib/common/xml.c:990>
          |       |   | | \-decompress_file() <char * () at ../lib/common/xml.c:901>
          |       |   | |   \-crm_perror()
          |       |   | \-cib_file_verify_digest() <gboolean () at ../lib/cib/cib_file.c:710>
          |       |   |   \-pcmk__verify_digest() <bool () at ../lib/common/digest.c:202>
          |       |   |     \-crm_perror()
          |       |   +-cib_file_backup() <int () at ../lib/cib/cib_file.c:812>
          |       |   | +-crm_perror()
          |       |   | +-pcmk__write_series_sequence() <void () at ../lib/common/io.c:187>
          |       |   | | \-crm_perror()
          |       |   | \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
          |       |   |   \-crm_perror()
          |       |   +-crm_perror()
          |       |   +-write_xml_fd() <int () at ../lib/common/xml.c:1255>
          |       |   | \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |       |   |   \-crm_perror()
          |       |   \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
          |       |     \-crm_perror()
          |       \-write_xml_file() <int () at ../lib/common/xml.c:1283>
          |         \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
          |           \-crm_perror()
          \-cib_file_new() <cib_t * () at ../lib/cib/cib_file.c:654>
            +-cib_file_perform_op_delegate() <int () at ../lib/cib/cib_file.c:295>
            | \-cib_file_process_request() <int () at ../lib/cib/cib_file.c:214>
            |   +-cib_perform_op() <int () at ../lib/cib/cib_utils.c:193>
            |   | +-patchset_process_digest() <void () at ../lib/common/patchset.c:377>
            |   | | \-calculate_xml_versioned_digest() <char * () at ../lib/common/digest.c:167>
            |   | |   \-calculate_xml_digest_v2() <char * () at ../lib/common/digest.c:92>
            |   | |     \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
            |   | |       \-write_xml_file() <int () at ../lib/common/xml.c:1283>
            |   | |         \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
            |   | |           \-crm_perror()
            |   | +-xml_apply_patchset() <int () at ../lib/common/patchset.c:1092>
            |   | | +-calculate_xml_versioned_digest() <char * () at ../lib/common/digest.c:167>
            |   | | | \-calculate_xml_digest_v2() <char * () at ../lib/common/digest.c:92>
            |   | | |   \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
            |   | | |     \-write_xml_file() <int () at ../lib/common/xml.c:1283>
            |   | | |       \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
            |   | | |         \-crm_perror()
            |   | | \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
            |   | |   \-write_xml_file() <int () at ../lib/common/xml.c:1283>
            |   | |     \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
            |   | |       \-crm_perror()
            |   | \-save_xml_to_file() <void () at ../lib/common/xml.c:1747>
            |   |   \-write_xml_file() <int () at ../lib/common/xml.c:1283>
            |   |     \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
            |   |       \-crm_perror()
            |   \-validate_xml_verbose() <gboolean () at ../lib/common/schemas.c:676>
            |     +-write_xml_fd() <int () at ../lib/common/xml.c:1255>
            |     | \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
            |     |   \-crm_perror()
            |     \-dump_file() <void () at ../lib/common/schemas.c:645>
            |       \-crm_perror()
            +-cib_file_signon() <int () at ../lib/cib/cib_file.c:420>
            | \-load_file_cib() <int () at ../lib/cib/cib_file.c:384>
            |   \-filename2xml() <xmlNode * () at ../lib/common/xml.c:990>
            |     \-decompress_file() <char * () at ../lib/common/xml.c:901>
            |       \-crm_perror()
            +-cib_file_signoff() <int () at ../lib/cib/cib_file.c:537>
            | +-cib_file_write_live() <int () at ../lib/cib/cib_file.c:455>
            | | +-crm_perror()
            | | \-cib_file_write_with_digest() <int () at ../lib/cib/cib_file.c:926>
            | |   +-cib_file_read_and_verify() <int () at ../lib/cib/cib_file.c:752>
            | |   | +-crm_perror()
            | |   | +-filename2xml() <xmlNode * () at ../lib/common/xml.c:990>
            | |   | | \-decompress_file() <char * () at ../lib/common/xml.c:901>
            | |   | |   \-crm_perror()
            | |   | \-cib_file_verify_digest() <gboolean () at ../lib/cib/cib_file.c:710>
            | |   |   \-pcmk__verify_digest() <bool () at ../lib/common/digest.c:202>
            | |   |     \-crm_perror()
            | |   +-cib_file_backup() <int () at ../lib/cib/cib_file.c:812>
            | |   | +-crm_perror()
            | |   | +-pcmk__write_series_sequence() <void () at ../lib/common/io.c:187>
            | |   | | \-crm_perror()
            | |   | \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
            | |   |   \-crm_perror()
            | |   +-crm_perror()
            | |   +-write_xml_fd() <int () at ../lib/common/xml.c:1255>
            | |   | \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
            | |   |   \-crm_perror()
            | |   \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
            | |     \-crm_perror()
            | \-write_xml_file() <int () at ../lib/common/xml.c:1283>
            |   \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
            |     \-crm_perror()
            \-cib_file_free() <int () at ../lib/cib/cib_file.c:582>
              \-cib_file_signoff() <int () at ../lib/cib/cib_file.c:537>
                +-cib_file_write_live() <int () at ../lib/cib/cib_file.c:455>
                | +-crm_perror()
                | \-cib_file_write_with_digest() <int () at ../lib/cib/cib_file.c:926>
                |   +-cib_file_read_and_verify() <int () at ../lib/cib/cib_file.c:752>
                |   | +-crm_perror()
                |   | +-filename2xml() <xmlNode * () at ../lib/common/xml.c:990>
                |   | | \-decompress_file() <char * () at ../lib/common/xml.c:901>
                |   | |   \-crm_perror()
                |   | \-cib_file_verify_digest() <gboolean () at ../lib/cib/cib_file.c:710>
                |   |   \-pcmk__verify_digest() <bool () at ../lib/common/digest.c:202>
                |   |     \-crm_perror()
                |   +-cib_file_backup() <int () at ../lib/cib/cib_file.c:812>
                |   | +-crm_perror()
                |   | +-pcmk__write_series_sequence() <void () at ../lib/common/io.c:187>
                |   | | \-crm_perror()
                |   | \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
                |   |   \-crm_perror()
                |   +-crm_perror()
                |   +-write_xml_fd() <int () at ../lib/common/xml.c:1255>
                |   | \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
                |   |   \-crm_perror()
                |   \-pcmk__sync_directory() <void () at ../lib/common/io.c:396>
                |     \-crm_perror()
                \-write_xml_file() <int () at ../lib/common/xml.c:1283>
                  \-write_xml_stream() <int () at ../lib/common/xml.c:1158>
                    \-crm_perror()

clumens avatar Aug 22 '23 16:08 clumens

It's interesting to see. I don't have a strong feeling one way or another.

Note we also have https://clusterlabs.org/pacemaker/global/ to drill down to see everywhere a symbol is used, but that is limited to releases, and doesn't show an overall visual call chain.

kgaillot avatar Jan 03 '24 17:01 kgaillot

cflow is not a great tool. It doesn't understand various bits of C99 syntax. If we want to be able to do something like this, we can whip something else up using gcc or one of the various other call graph generating tools later.

clumens avatar Apr 16 '24 15:04 clumens