Created
October 2, 2019 19:46
-
-
Save dogbert17/d6291bfbc9b69130a8cd5761f56ba704 to your computer and use it in GitHub Desktop.
Valgrind vs --profile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dogbert@dogbert-VirtualBox ~/repos/rakudo $ ./perl6-valgrind-m --profile -Ilib t/spec/S03-junctions/autothreading.t | |
================================================================================================ | |
This is Rakudo Perl 6 running in valgrind, a tool for debugging and profiling programs. | |
Running a program in valgrind usually takes *a lot* more time than running it directly, | |
so please be patient. | |
Valgrind options can be added with MVM_VALGRIND_OPTS environment variable. | |
This Rakudo version is 2019.07.1.368.g.1.e.2.b.0.ec built on MoarVM version 2019.07.1.246.g.44811.ca, | |
running on linuxmint (18.3.Sylvia) / linux (42.16.04.1.Ubuntu.SMP.Tue.Oct.10.16.32.20.UTC.2017) | |
------------------------------------------------------------------------------------------------ | |
==1835== Memcheck, a memory error detector | |
==1835== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. | |
==1835== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info | |
==1835== Command: /home/dogbert/repos/rakudo/nqp/MoarVM/../../install/bin/moar --execname=/home/dogbert/repos/rakudo/perl6-valgrind-m --libpath=/home/dogbert/repos/rakudo --libpath=/home/dogbert/repos/rakudo/blib --libpath= --libpath=/home/dogbert/repos/rakudo/install/share/nqp/lib /home/dogbert/repos/rakudo/perl6.moarvm --nqp-lib=/home/dogbert/repos/rakudo/blib --profile -Ilib t/spec/S03-junctions/autothreading.t | |
==1835== | |
--1835-- WARNING: unhandled amd64-linux syscall: 332 | |
--1835-- You may be able to write your own handler. | |
--1835-- Read the file README_MISSING_SYSCALL_OR_IOCTL. | |
--1835-- Nevertheless we consider this a bug. Please report | |
--1835-- it at http://valgrind.org/support/bug_reports.html. | |
1..106 | |
ok 1 - called lots of times :-) | |
ok 2 - found right answer | |
ok 3 - method called right number of times | |
ok 4 - right values passed to method | |
ok 5 - method called right number of times | |
ok 6 - junction structure maintained | |
ok 7 - correct multi-sub called right number of times | |
ok 8 - incorrect multi-sub not called | |
ok 9 - incorrect multi-sub not called | |
ok 10 - junction structure maintained | |
ok 11 - correct multi-sub called right number of times | |
ok 12 - incorrect multi-sub not called | |
ok 13 - incorrect multi-sub not called | |
ok 14 - correct multi-sub called right number of times (junction of many types) | |
ok 15 - correct multi-sub called right number of times (junction of many types) | |
ok 16 - incorrect multi-sub not called | |
ok 17 - correct multi-sub called again right number of times (junction of many types) | |
ok 18 - correct multi-sub called again right number of times (junction of many types) | |
ok 19 - incorrect multi-sub again not called | |
ok 20 - non-junctional dispatch still works | |
ok 21 - non-junctional dispatch still works | |
ok 22 - non-junctional dispatch still works | |
ok 23 - correct multi-method called right number of times | |
ok 24 - incorrect multi-method not called | |
ok 25 - incorrect multi-method not called | |
ok 26 - junction structure maintained | |
ok 27 - correct multi-method called right number of times | |
ok 28 - incorrect multi-method not called | |
ok 29 - incorrect multi-method not called | |
ok 30 - correct multi-method called right number of times (junction of many types) | |
ok 31 - correct multi-method called right number of times (junction of many types) | |
ok 32 - incorrect multi-method not called | |
ok 33 - auto-threaded over named parameters to call sub enough times | |
ok 34 - got array of right size to check what was called | |
ok 35 - called with correct parameters | |
ok 36 - called with correct parameters | |
ok 37 - called with correct parameters | |
ok 38 - called with correct parameters | |
ok 39 - auto-threaded over named parameters to call multi-sub variant enough times | |
ok 40 - auto-threaded over named parameters to call multi-sub variant enough times | |
ok 41 - got array of right size to check what was called | |
ok 42 - called with correct parameters | |
ok 43 - called with correct parameters | |
ok 44 - called with correct parameters | |
ok 45 - called with correct parameters | |
ok 46 - basic auto-threading over invocant works | |
ok 47 - basic auto-threading over invocant works | |
ok 48 - auto-threading over invocant of nested junctions works | |
ok 49 - auto-threading over invocant of nested junctions works | |
ok 50 - auto-threading over invocant produced correct junctional result | |
ok 51 - auto-threading over invocant and parameters works | |
ok 52 - prefix:<+> autothreads (1) | |
ok 53 - prefix:<+> autothreads (2) | |
ok 54 - prefix:<+> autothreads (3) | |
ok 55 - primality test for 2 works | |
ok 56 - primality test for 3 works | |
ok 57 - primality test for 4 works | |
ok 58 - primality test for 5 works | |
ok 59 - primality test for 6 works | |
ok 60 - primality test for 7 works | |
ok 61 - primality test for 8 works | |
ok 62 - primality test for 9 works | |
ok 63 - primality test for 10 works | |
ok 64 - primality test for 11 works | |
ok 65 - primality test for 12 works | |
ok 66 - primality test for 13 works | |
ok 67 - primality test for 14 works | |
ok 68 - primality test for 15 works | |
ok 69 - can autothread over array indexes | |
ok 70 - substr() | |
ok 71 - substr() called 4 times | |
ok 72 - autothreading over array parameters (0) | |
ok 73 - autothreading over array parameters (1) | |
ok 74 - autothreading over array parameters (2) | |
ok 75 - autothreading over array parameters (3) | |
ok 76 - do not autothread over blocks by default | |
ok 77 - do autothread over blocks with explicit Any | |
ok 78 - infix:<ne> collapses the junction (1) | |
ok 79 - infix:<ne> collapses the junction (2) | |
ok 80 - ... and the result is False | |
ok 81 - infix:<!eq> collapses the junction (1) | |
ok 82 - infix:<!eq> collapses the junction (2) | |
ok 83 - ... and the result is False | |
ok 84 - != autothreads like not == (1) | |
ok 85 - != autothreads like not == (2) | |
ok 86 - named-only params autothread correctly | |
ok 87 - infix | does not flatten ranges | |
ok 88 - an & junction right of a | junction will be autothreaded first | |
ok 89 - an & junction left of a | junction will be autothreaded first | |
ok 90 - all/Mu smartmatch True | |
ok 91 - all/Any smartmatch autothreads | |
ok 92 - all/Cool smartmatch autothreads True | |
ok 93 - all/Int smartmatch autothreads True | |
ok 94 - all/Real smartmatch autothreads True | |
ok 95 - all/Int smartmatch autothreads False | |
ok 96 - all/Junction smartmatch does not autothread | |
ok 97 - any/Int smartmatch autothreads True | |
ok 98 - any/Rat smartmatch autothreads True | |
ok 99 - any/Str smartmatch autothreads True | |
ok 100 - any/Num smartmatch autothreads False | |
ok 101 - any/Junction smartmatch does not autothread | |
ok 102 - Mu/Junction smartmatch False | |
ok 103 - Junction/Junction smartmatch True | |
ok 104 - Junction/Mu smartmatch True | |
1..16 | |
ok 1 - any (true by True Bool) | |
ok 2 - any (true by False Bool) | |
ok 3 - any (false) | |
ok 4 - all (true by True Bool) | |
ok 5 - all (true by False Bool) | |
ok 6 - all (true by Mixed Bools) | |
ok 7 - all (false; no Bools) | |
ok 8 - all (false not all are Bools) | |
ok 9 - one (true by True Bool) | |
ok 10 - one (true by False Bool) | |
ok 11 - one (false, too few) | |
ok 12 - one (false, too many) | |
ok 13 - none (true) | |
ok 14 - none (false by True Bool) | |
ok 15 - none (false by False Bool) | |
ok 16 - none (false by True Bool) | |
ok 105 - smartmatch against Bool:U | |
1..2 | |
1..14 | |
ok 1 - any() -> True | |
ok 2 - any() -> False | |
ok 3 - any(Failure) -> false | |
ok 4 - none() -> True | |
ok 5 - none(Failure) -> True | |
ok 6 - none() -> False | |
ok 7 - all() -> True | |
ok 8 - all() -> False (1) | |
ok 9 - all() -> False (2) | |
ok 10 - all(Failure) -> False (3) | |
ok 11 - one() -> True | |
ok 12 - one() -> False (1) | |
ok 13 - one() -> False (2) | |
ok 14 - one(Failure) -> False (3) | |
ok 1 - defined() as a sub | |
1..14 | |
ok 1 - any() -> True | |
ok 2 - any() -> False | |
ok 3 - any(Failure) -> false | |
ok 4 - none() -> True | |
ok 5 - none(Failure) -> True | |
ok 6 - none() -> False | |
ok 7 - all() -> True | |
ok 8 - all() -> False (1) | |
ok 9 - all() -> False (2) | |
ok 10 - all(Failure) -> False (3) | |
ok 11 - one() -> True | |
ok 12 - one() -> False (1) | |
ok 13 - one() -> False (2) | |
ok 14 - one(Failure) -> False (3) | |
ok 2 - defined() as a method | |
ok 106 - defined with Junctions autothreads | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x50876FA: MVM_intcache_get (intcache.c:42) | |
==1835== by 0x50CDE77: MVM_repr_box_int (reprconv.c:656) | |
==1835== by 0x51D40AB: box_i (instrument.c:287) | |
==1835== by 0x51D52E2: dump_thread_data (instrument.c:634) | |
==1835== by 0x51D5C5E: MVM_profile_dump_instrumented_data (instrument.c:756) | |
==1835== by 0x509D687: finish_gc (orchestrate.c:187) | |
==1835== by 0x509DF58: run_gc (orchestrate.c:448) | |
==1835== by 0x509E618: MVM_gc_enter_from_allocator (orchestrate.c:602) | |
==1835== by 0x51D5E25: dump_data (instrument.c:794) | |
==1835== by 0x51D5EFF: MVM_profile_instrumented_end (instrument.c:814) | |
==1835== by 0x51D899F: MVM_profile_end (profile.c:54) | |
==1835== by 0x5049DC5: MVM_interp_run (interp.c:4389) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5087701: MVM_intcache_get (intcache.c:42) | |
==1835== by 0x50CDE77: MVM_repr_box_int (reprconv.c:656) | |
==1835== by 0x51D40AB: box_i (instrument.c:287) | |
==1835== by 0x51D52E2: dump_thread_data (instrument.c:634) | |
==1835== by 0x51D5C5E: MVM_profile_dump_instrumented_data (instrument.c:756) | |
==1835== by 0x509D687: finish_gc (orchestrate.c:187) | |
==1835== by 0x509DF58: run_gc (orchestrate.c:448) | |
==1835== by 0x509E618: MVM_gc_enter_from_allocator (orchestrate.c:602) | |
==1835== by 0x51D5E25: dump_data (instrument.c:794) | |
==1835== by 0x51D5EFF: MVM_profile_instrumented_end (instrument.c:814) | |
==1835== by 0x51D899F: MVM_profile_end (profile.c:54) | |
==1835== by 0x5049DC5: MVM_interp_run (interp.c:4389) | |
==1835== | |
==1835== Use of uninitialised value of size 8 | |
==1835== at 0x5087772: MVM_intcache_get (intcache.c:52) | |
==1835== by 0x50CDE77: MVM_repr_box_int (reprconv.c:656) | |
==1835== by 0x51D40AB: box_i (instrument.c:287) | |
==1835== by 0x51D52E2: dump_thread_data (instrument.c:634) | |
==1835== by 0x51D5C5E: MVM_profile_dump_instrumented_data (instrument.c:756) | |
==1835== by 0x509D687: finish_gc (orchestrate.c:187) | |
==1835== by 0x509DF58: run_gc (orchestrate.c:448) | |
==1835== by 0x509E618: MVM_gc_enter_from_allocator (orchestrate.c:602) | |
==1835== by 0x51D5E25: dump_data (instrument.c:794) | |
==1835== by 0x51D5EFF: MVM_profile_instrumented_end (instrument.c:814) | |
==1835== by 0x51D899F: MVM_profile_end (profile.c:54) | |
==1835== by 0x5049DC5: MVM_interp_run (interp.c:4389) | |
==1835== | |
Writing profiler output to profile-1570045425.032468.html | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5077FE9: MVM_coerce_i_s (coerce.c:207) | |
==1835== by 0x5078612: MVM_coerce_smart_stringify (coerce.c:320) | |
==1835== by 0x155AC777: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5077FF0: MVM_coerce_i_s (coerce.c:207) | |
==1835== by 0x5078612: MVM_coerce_smart_stringify (coerce.c:320) | |
==1835== by 0x155AC777: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Use of uninitialised value of size 8 | |
==1835== at 0x5078021: MVM_coerce_i_s (coerce.c:209) | |
==1835== by 0x5078612: MVM_coerce_smart_stringify (coerce.c:320) | |
==1835== by 0x155AC777: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5077F5C: i64toa_naive (coerce.c:193) | |
==1835== by 0x507804A: MVM_coerce_i_s (coerce.c:214) | |
==1835== by 0x5078612: MVM_coerce_smart_stringify (coerce.c:320) | |
==1835== by 0x155AC777: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5077EF0: u64toa_naive_worker (coerce.c:181) | |
==1835== by 0x5077F83: i64toa_naive (coerce.c:197) | |
==1835== by 0x507804A: MVM_coerce_i_s (coerce.c:214) | |
==1835== by 0x5078612: MVM_coerce_smart_stringify (coerce.c:320) | |
==1835== by 0x155AC777: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5188EF7: MVM_nfg_is_concat_stable (nfg.c:413) | |
==1835== by 0x5191010: nfg_is_join_stable (ops.c:1931) | |
==1835== by 0x51910F0: join_check_stability (ops.c:1947) | |
==1835== by 0x5191B5F: MVM_string_join (ops.c:2067) | |
==1835== by 0x155ACFB1: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5188F1D: MVM_nfg_is_concat_stable (nfg.c:420) | |
==1835== by 0x5191010: nfg_is_join_stable (ops.c:1931) | |
==1835== by 0x51910F0: join_check_stability (ops.c:1947) | |
==1835== by 0x5191B5F: MVM_string_join (ops.c:2067) | |
==1835== by 0x155ACFB1: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5188F3B: MVM_nfg_is_concat_stable (nfg.c:427) | |
==1835== by 0x5191010: nfg_is_join_stable (ops.c:1931) | |
==1835== by 0x51910F0: join_check_stability (ops.c:1947) | |
==1835== by 0x5191B5F: MVM_string_join (ops.c:2067) | |
==1835== by 0x155ACFB1: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5188F57: MVM_nfg_is_concat_stable (nfg.c:431) | |
==1835== by 0x5191010: nfg_is_join_stable (ops.c:1931) | |
==1835== by 0x51910F0: join_check_stability (ops.c:1947) | |
==1835== by 0x5191B5F: MVM_string_join (ops.c:2067) | |
==1835== by 0x155ACFB1: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5188F25: MVM_nfg_is_concat_stable (nfg.c:420) | |
==1835== by 0x5191010: nfg_is_join_stable (ops.c:1931) | |
==1835== by 0x51910F0: join_check_stability (ops.c:1947) | |
==1835== by 0x5191B5F: MVM_string_join (ops.c:2067) | |
==1835== by 0x155ACFB1: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5188F35: MVM_nfg_is_concat_stable (nfg.c:427) | |
==1835== by 0x5191010: nfg_is_join_stable (ops.c:1931) | |
==1835== by 0x51910F0: join_check_stability (ops.c:1947) | |
==1835== by 0x5191B5F: MVM_string_join (ops.c:2067) | |
==1835== by 0x155ACFB1: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5188F4E: MVM_nfg_is_concat_stable (nfg.c:431) | |
==1835== by 0x5191010: nfg_is_join_stable (ops.c:1931) | |
==1835== by 0x51910F0: join_check_stability (ops.c:1947) | |
==1835== by 0x5191B5F: MVM_string_join (ops.c:2067) | |
==1835== by 0x155ACFB1: ??? | |
==1835== by 0x520AF7D: MVM_jit_code_enter (interface.c:24) | |
==1835== by 0x5059B0B: MVM_interp_run (interp.c:6308) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x5183E2F: MVM_string_ci_get_codepoint (iter.h:313) | |
==1835== by 0x51850A2: MVM_string_utf8_encode_substr (utf8.c:545) | |
==1835== by 0x51904EC: MVM_string_encode_config (ops.c:1728) | |
==1835== by 0x5190987: MVM_string_encode_to_buf_config (ops.c:1797) | |
==1835== by 0x5190A4A: MVM_string_encode_to_buf (ops.c:1812) | |
==1835== by 0x50340B4: MVM_interp_run (interp.c:1769) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Conditional jump or move depends on uninitialised value(s) | |
==1835== at 0x518403A: classify (utf8.c:99) | |
==1835== by 0x518413C: utf8_encode (utf8.c:133) | |
==1835== by 0x51850E6: MVM_string_utf8_encode_substr (utf8.c:550) | |
==1835== by 0x51904EC: MVM_string_encode_config (ops.c:1728) | |
==1835== by 0x5190987: MVM_string_encode_to_buf_config (ops.c:1797) | |
==1835== by 0x5190A4A: MVM_string_encode_to_buf (ops.c:1812) | |
==1835== by 0x50340B4: MVM_interp_run (interp.c:1769) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== | |
==1835== Syscall param write(buf) points to uninitialised byte(s) | |
==1835== at 0x5AF12DD: ??? (syscall-template.S:84) | |
==1835== by 0x50B520C: perform_write (syncfile.c:77) | |
==1835== by 0x50B5827: write_bytes (syncfile.c:219) | |
==1835== by 0x50B26A9: MVM_io_write_bytes (io.c:158) | |
==1835== by 0x5045A78: MVM_interp_run (interp.c:3884) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) | |
==1835== Address 0x12a87591 is 6,257 bytes inside a block of size 21,798 alloc'd | |
==1835== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) | |
==1835== by 0x5183561: MVM_malloc (alloc.h:2) | |
==1835== by 0x5185058: MVM_string_utf8_encode_substr (utf8.c:538) | |
==1835== by 0x51904EC: MVM_string_encode_config (ops.c:1728) | |
==1835== by 0x5190987: MVM_string_encode_to_buf_config (ops.c:1797) | |
==1835== by 0x5190A4A: MVM_string_encode_to_buf (ops.c:1812) | |
==1835== by 0x50340B4: MVM_interp_run (interp.c:1769) | |
==1835== by 0x51E6A68: MVM_vm_run_file (moar.c:460) | |
==1835== by 0x4016E6: main (main.c:302) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment