bkryza / clang-uml

Customizable automatic UML diagram generator for C++ based on Clang.
Apache License 2.0
610 stars 44 forks source link

Bug report (Segmentation fault) #199

Closed tom--bo closed 1 year ago

tom--bo commented 1 year ago

Hi. Thank you for your great product. I tried to draw a sequence diagram, but failed with Segmentation fault (core dumped).

I'll describe what I did.

# Prepare MySQL code and build with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
$ git clone https://github.com/mysql/mysql-server
$ cd mysql-server
$ git switch mysql-8.0.34

$ mkdir bld
$ cd bld
$ cmake .. \
-DDOWNLOAD_BOOST=1 \
-DWITH_BOOST=boost \
-DADD_GDB_INDEX=true \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_C_FLAGS="-Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable"
$ make -j $(($(nproc)/2))
$ cd ..

Write config like below

$ cat clang-uml-sample.conf 
compilation_database_dir: bld
output_directory: diagrams
diagrams:
  sequence_sample:
    type: sequence
    glob:
      - ./storage/innobase/buf/buf0buf.cc
    from:
      - function: "buf_flush_page(buf_pool_t *buf_pool, buf_page_t *bpage, buf_flush_t flush_type, bool sync)"
    plantuml:
      after:
        - 'Sequence of buf_flush_page()'

And execute clang-uml (I got error)

$ clang-uml -c clang-uml-sample.conf > log.txt
Segmentation fault (core dumped)
tom--bo commented 1 year ago

log.txt is below

$ cat log.txt 
[info] [tid 83748] [cli_handler.cc:293] Loaded clang-uml config from clang-uml-sample.conf
[info] [tid 83748] [cli_handler.cc:316] Loading compilation database from /home/tom__bo/workdir/src/mysql-server/bld directory
[info] [tid 83759] [generators.h:368] Generating diagram sequence_sample
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
[info] [tid 83759] [translation_unit_visitor.cc:1764] Unsupported argument type 8
...
tom--bo commented 1 year ago

make test was failed as below, Is this my environmental issue? I pulled master branch and tested with the latest version (commit 57bc2f7309a7f8c245c3b76ae9df8826262791c5)

$ make test
cmake -S . -B debug \
    -DGIT_VERSION=0.4.1-3-g57bc2f7 \
    -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
    -DCMAKE_BUILD_TYPE=Debug \
    -DCMAKE_CXX_FLAGS="" \
    -DCMAKE_EXE_LINKER_FLAGS="" \
    -DLLVM_VERSION=
-- clang-uml version: 0.4.1-3-g57bc2f7
-- Checking for LLVM and Clang...
-- Found LLVM 14.0.0
-- Using LLVMConfig.cmake in: /usr/lib/llvm-14/cmake
-- LLVM library dir: /usr/lib/llvm-14/lib
-- Found LibTooling libraries: clang-cpp;LLVM
-- Checking for yaml-cpp...
-- Found yaml-cpp libraries: yaml-cpp
-- Configuring done
-- Generating done
-- Build files have been written to: /home/tom__bo/workdir/src/clang-uml/debug
echo "Using 32 cores"
Using 32 cores
make -C debug -j32
make[1]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[2]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
Consolidate compiler generated dependencies of target clang-umllib
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
[ 32%] Built target clang-umllib
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
Consolidate compiler generated dependencies of target test_util
Consolidate compiler generated dependencies of target test_model
Consolidate compiler generated dependencies of target test_filters
Consolidate compiler generated dependencies of target clang-uml
Consolidate compiler generated dependencies of target test_decorator_parser
Consolidate compiler generated dependencies of target test_thread_pool_executor
Consolidate compiler generated dependencies of target test_compilation_database
Consolidate compiler generated dependencies of target test_query_driver_output_extractor
Consolidate compiler generated dependencies of target test_cli_handler
Consolidate compiler generated dependencies of target test_config
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
Consolidate compiler generated dependencies of target test_cases
[ 35%] Built target test_query_driver_output_extractor
[ 35%] Built target test_decorator_parser
[ 35%] Built target test_thread_pool_executor
[ 36%] Built target test_util
[ 37%] Built target test_model
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
[ 38%] Built target test_filters
[ 39%] Built target test_cli_handler
[ 40%] Built target clang-uml
[ 40%] Built target test_compilation_database
[ 41%] Built target test_config
make[3]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
[100%] Built target test_cases
make[2]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make[1]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
CTEST_OUTPUT_ON_FAILURE=1 make -C debug test
make[1]: Entering directory '/home/tom__bo/workdir/src/clang-uml/debug'
Running tests...
Test project /home/tom__bo/workdir/src/clang-uml/debug
      Start  1: test_util
 1/10 Test  #1: test_util ............................   Passed    0.02 sec
      Start  2: test_model
 2/10 Test  #2: test_model ...........................   Passed    0.02 sec
      Start  3: test_cases
 3/10 Test  #3: test_cases ...........................***Failed   26.79 sec
[error] [tid 80791] [generator.h:412] Failed to render PlantUML directive due to unresolvable alias: NoSuchClass
[error] [tid 80791] [generator.h:362] Failed to render MermaidJS directive due to unresolvable alias: NoSuchClass

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_cases is a Catch v2.13.8 host application.
Run with -? for options

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
t00056
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/home/tom__bo/workdir/src/clang-uml/tests/t00056/test_case.h:19
...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

/home/tom__bo/workdir/src/clang-uml/tests/t00056/test_case.h:62: FAILED:
  REQUIRE_THAT( src, IsConceptRequirement( _A("convertible_to_string<T>"), "std::string{s}") )
with expansion:
  "@startuml
  class "greater_than_simple<T,L>" as C_0000902541696362244204
  class C_0000902541696362244204 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L8{greater_than_simple}]] {
  }
  class "greater_than_with_requires<T,P>" as C_0001830716585637735576
  class C_0001830716585637735576 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L11{greater_than_with_requires}]] {
  (T l,P r)
  ..
  sizeof (l) > sizeof (r)
  }
  class "max_four_bytes<T>" as C_0000385255522691733325
  class C_0000385255522691733325 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L16{max_four_bytes}]] {
  }
  class "iterable<T>" as C_0000392540961352249242
  class C_0000392540961352249242 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L20{iterable}]] {
  (T container)
  ..
  container.begin()
  container.end()
  }
  class "has_value_type<T>" as C_0001850394311226276678
  class C_0001850394311226276678 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L27{has_value_type}]] {
  ()
  ..
  typename T::value_type
  }
  class "convertible_to_string<T>" as C_0000137304962071054497
  class C_0000137304962071054497 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L30{convertible_to_string}]] {
  (T s)
  ..
  std::string({s})
  {std::to_string(s)} noexcept
  {std::to_string(s)} -> std::same_as<std::string>
  }
  class "iterable_with_value_type<T>" as C_0001043398062146751019
  class C_0001043398062146751019 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L46{iterable_with_value_type}]] {
  }
  class "iterable_or_small_value_type<T>" as C_0000866345615551223718
  class C_0000866345615551223718 <<concept>> [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L49{iterable_or_small_value_type}]] {
  }
  class "A<max_four_bytes T>" as C_0001418333499545421661
  class C_0001418333499545421661 [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L53{A}]] {
  __
  +a : T [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L54{a}]]]
  }
  class "B<T>" as C_0001814355496814977880
  class C_0001814355496814977880 [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L60{B}]] {
  __
  +b : T [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L61{b}]]]
  }
  class "C<convertible_to_string T>" as C_0001512618198241549089
  class C_0001512618198241549089 [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L70{C}]] {
  __
  +c : T [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L71{c}]]]
  }
  class "D<iterable T1,T2,iterable T3,T4,T5>" as C_0001635109601630198093
  class C_0001635109601630198093 [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L76{D}]] {
  __
  }
  class "E<T1,T2,T3>" as C_0001429225801945621089
  class C_0001429225801945621089 [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L80{E}]] {
  __
  +e1 : T1 [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L81{e1}]]]
  +e2 : T2 [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L82{e2}]]]
  +e3 : T3 [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L83{e3}]]]
  }
  class "F<T1,T2,T3>" as C_0000856301122972546034
  class C_0000856301122972546034 [[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L88{F}]] {
  __
  +f1 : T1 [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L89{f1}]]]
  +f2 : T2 [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L90{f2}]]]
  +f3 : T3 [[[https://github.com/bkryza/clang-uml/blob/57bc2f7309a7f8c245c3b76ae9df8826262791c5/tests/t00056/t00056.cc#L91{f3}]]]
  }
  C_0000137304962071054497 ..> C_0000385255522691733325 : T
  C_0001043398062146751019 ..> C_0000392540961352249242 : T
  C_0001043398062146751019 ..> C_0001850394311226276678 : T
  C_0000866345615551223718 ..> C_0001043398062146751019 : T
  C_0000866345615551223718 ..> C_0000385255522691733325 : T
  C_0001418333499545421661 ..> C_0000385255522691733325 : T
  C_0001814355496814977880 ..> C_0000866345615551223718 : T
  C_0001512618198241549089 ..> C_0000137304962071054497 : T
  C_0001635109601630198093 ..> C_0000392540961352249242 : T1
  C_0001635109601630198093 ..> C_0000392540961352249242 : T3
  C_0001635109601630198093 ..> C_0000385255522691733325 : T2
  C_0001635109601630198093 ..> C_0000385255522691733325 : T5
  C_0001429225801945621089 ..> C_0001830716585637735576 : T1,T3
  C_0000856301122972546034 ..> C_0000902541696362244204 : T1,T3

'Generated with clang-uml, version 0.4.1-3-g57bc2f7
  'LLVM version Ubuntu clang version 14.0.0-1ubuntu1.1
  @enduml
  " contains: "std::string{s}"

===============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
test cases:  119 |  118 passed | 1 failed
assertions: 3575 | 3574 passed | 1 failed

      Start  4: test_compilation_database
 4/10 Test  #4: test_compilation_database ............   Passed    0.06 sec
      Start  5: test_decorator_parser
 5/10 Test  #5: test_decorator_parser ................   Passed    0.02 sec
      Start  6: test_config
 6/10 Test  #6: test_config ..........................   Passed    0.27 sec
      Start  7: test_cli_handler
 7/10 Test  #7: test_cli_handler .....................   Passed    0.13 sec
      Start  8: test_filters
 8/10 Test  #8: test_filters .........................   Passed    0.38 sec
      Start  9: test_thread_pool_executor
 9/10 Test  #9: test_thread_pool_executor ............   Passed    1.02 sec
      Start 10: test_query_driver_output_extractor
10/10 Test #10: test_query_driver_output_extractor ...   Passed    0.02 sec

90% tests passed, 1 tests failed out of 10

Total Test time (real) =  28.71 sec

The following tests FAILED:
      3 - test_cases (Failed)
Errors while running CTest
make[1]: *** [Makefile:91: test] Error 8
make[1]: Leaving directory '/home/tom__bo/workdir/src/clang-uml/debug'
make: *** [Makefile:88: test] Error 2
bkryza commented 1 year ago

@tom--bo I've managed to reproduce the problem and I'll try to fix it.

In the meantime, don't worry about this test error - this is due to the fact that each LLVM version has slightly different way of rendering c++ concept requirements to string, and apparently I haven't tested against LLVM 14 in a while.

bkryza commented 1 year ago

@tom--bo Ok, I've fixed it hopefully, actually this was a good issue as it found an old bug as well as a regression from few days back.

Please try to pull the latest commit from master branch and rebuild. Then the following config file:

compilation_database_dir: bld
output_directory: diagrams
diagrams:
  sequence_sample:
    type: sequence
    title: "Sequence of buf_flush_page()"
    relative_to: .
    combine_free_functions_into_file_participants: true
    glob:
      - ./storage/innobase/buf/*.cc
    include:
      paths:
        - storage/innobase/buf
    from:
      - function: "buf_flush_page(buf_pool_t *,buf_page_t *,buf_flush_t,bool)"

should produce the following diagram (here in MermaidJS format - it does look a little bit better in PlantUML IMHO):

---
title: Sequence of buf_flush_page()
---
sequenceDiagram
    participant C_0001528625864905162466 as storage/innobase/buf/buf0flu.cc
    * ->> C_0001528625864905162466 : buf_flush_page(buf_pool_t *,buf_page_t *,buf_flush_t,bool)
    activate C_0001528625864905162466
    alt
    alt
    alt
    else
    C_0001528625864905162466 ->> C_0001528625864905162466 : buf_flush_sync_datafiles()
    activate C_0001528625864905162466
    deactivate C_0001528625864905162466
    end
    end
    C_0001528625864905162466 ->> C_0001528625864905162466 : buf_flush_write_block_low(buf_page_t *,buf_flush_t,bool)
    activate C_0001528625864905162466
    alt
    else BUF_BLOCK_POOL_WATCH
    C_0001528625864905162466 ->> C_0001528625864905162466 : buf_flush_init_for_writing(const buf_block_t *,byte *,void *,lsn_t,bool,bool)
    activate C_0001528625864905162466
    alt
    alt
    else FIL_PAGE_TYPE_ALLOCATED
    C_0001528625864905162466 ->> C_0001528625864905162466 : buf_flush_update_zip_checksum(buf_frame_t *,ulint,lsn_t,bool)
    activate C_0001528625864905162466
    deactivate C_0001528625864905162466
    end
    end
    deactivate C_0001528625864905162466
    end
    deactivate C_0001528625864905162466
    end
    C_0001528625864905162466 -->> * : 
    deactivate C_0001528625864905162466

You can omit the include filter:

    include:
      paths:
        - storage/innobase/buf

but the diagram then has 880K lines of PlantUML and is not viewable - at least I didn't want to wait that long. If this diagram is to small, you can try to extend the paths filter (or add other filters) to limit/extend what is included in the diagram...

tom--bo commented 1 year ago

@bkryza Thank you for dealing with it very quickly! It looks great. I also confirmed that I can generate disgram with suggested config file. It takes few minutes, and 38 lines of PlantUML as below, but I agree with you ("MermaidJS format - it does look a little bit better in PlantUML IMHO")

@startuml
title Sequence of buf_flush_page()
participant "storage/innobase/buf/buf0flu.cc" as C_0001506545791700757974
[-> C_0001506545791700757974 : buf_flush_page(buf_pool_t *,buf_page_t *,buf_flush_t,bool)
activate C_0001506545791700757974
alt
alt
alt
else
C_0001506545791700757974 -> C_0001506545791700757974 : buf_flush_sync_datafiles()
activate C_0001506545791700757974
deactivate C_0001506545791700757974
end
end
C_0001506545791700757974 -> C_0001506545791700757974 : buf_flush_write_block_low(buf_page_t *,buf_flush_t,bool)
activate C_0001506545791700757974
group switch
else BUF_BLOCK_POOL_WATCH
C_0001506545791700757974 -> C_0001506545791700757974 : buf_flush_init_for_writing(const buf_block_t *,byte *,void *,lsn_t,bool,bool)
activate C_0001506545791700757974
alt
group switch
else FIL_PAGE_TYPE_ALLOCATED
C_0001506545791700757974 -> C_0001506545791700757974 : buf_flush_update_zip_checksum(buf_frame_t *,ulint,lsn_t,bool)
activate C_0001506545791700757974
deactivate C_0001506545791700757974
end
end
deactivate C_0001506545791700757974
end
deactivate C_0001506545791700757974
end
[<-- C_0001506545791700757974
deactivate C_0001506545791700757974

'Generated with clang-uml, version 0.4.1-4-g79801b2
'LLVM version Ubuntu clang version 14.0.0-1ubuntu1.1
@enduml

Thank you very much!