• "stack smashing detected"

    From DFS@21:1/5 to All on Wed Jun 12 17:19:16 2024
    Same C program I just made a post about 'undefined behavior' on.

    I just noticed I get "stack smashing detected" only when I run the
    program using a dataset of 75+ consecutive integers.

    set of 2 to 74 consecutive values: no problem.
    set of random values of any size: no problem.
    75+ consecutive values: problem

    Any easy way to find out what's causing this issue (probably a buffer overflow)?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to DFS on Thu Jun 13 00:36:49 2024
    DFS <nospam@dfs.com> writes:

    Same C program I just made a post about 'undefined behavior' on.

    I just noticed I get "stack smashing detected" only when I run the program using a dataset of 75+ consecutive integers.

    set of 2 to 74 consecutive values: no problem.
    set of random values of any size: no problem.
    75+ consecutive values: problem

    Any easy way to find out what's causing this issue (probably a buffer overflow)?

    I compiled using -fsanitize=undefined and at runtime I get:

    $ ./dfs 70 -c
    70 Consecutive:
    No commas : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
    dfs.c:126:18: runtime error: index 70 out of bounds for type 'int [*]'
    ...

    Line 126:

    if(nums[i]-nums[i+1]!=0) {ucnt=1;} else {ucnt++;}

    nums is a VLA declared int nums[N]; and i runs from 0 to i < N (70 in
    this run). When i == 69 (the max) nums[i+1] is undefined (it's out of
    bounds).

    If I run

    $ ./dfs 1 -c
    1 Consecutive:
    No commas : 1
    dfs.c:126:18: runtime error: index 1 out of bounds for type 'int [*]' dfs.c:161:14: runtime error: index -1 out of bounds for type 'int [*]' dfs.c:162:32: runtime error: index 1 out of bounds for type 'int [*]'

    I see two further problems. With some stats you will have to set a
    minimum for N, but the first problem is just an incorrect index.

    BTW, when I was starting out, I'd give my right arm for gcc's -fsanitize=undefined and/or valgrind.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From DFS@21:1/5 to Ben Bacarisse on Wed Jun 12 20:29:23 2024
    On 6/12/2024 7:36 PM, Ben Bacarisse wrote:
    DFS <nospam@dfs.com> writes:

    Same C program I just made a post about 'undefined behavior' on.

    I just noticed I get "stack smashing detected" only when I run the program >> using a dataset of 75+ consecutive integers.

    set of 2 to 74 consecutive values: no problem.
    set of random values of any size: no problem.
    75+ consecutive values: problem

    Any easy way to find out what's causing this issue (probably a buffer
    overflow)?

    I compiled using -fsanitize=undefined and at runtime I get:

    $ ./dfs 70 -c
    70 Consecutive:
    No commas : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
    dfs.c:126:18: runtime error: index 70 out of bounds for type 'int [*]'
    ...

    Line 126:

    if(nums[i]-nums[i+1]!=0) {ucnt=1;} else {ucnt++;}

    nums is a VLA declared int nums[N];


    int nums[N] is OK isn't it, if I'm not running huge datasets?

    or should you always malloc:
    int *nums = malloc(N * sizeof(int));


    and i runs from 0 to i < N (70 in
    this run). When i == 69 (the max) nums[i+1] is undefined (it's out of bounds).

    Good catch. Fixed.

    The code worked even with that bug - it always correctly identifies the mode(s), according to that website. But I probably got lucky and the
    mode(s) weren't the last data point.

    I also no longer run that mode-analysis routine for consecutive datasets (because they have no repeating values).




    If I run

    $ ./dfs 1 -c
    1 Consecutive:
    No commas : 1
    dfs.c:126:18: runtime error: index 1 out of bounds for type 'int [*]' dfs.c:161:14: runtime error: index -1 out of bounds for type 'int [*]' dfs.c:162:32: runtime error: index 1 out of bounds for type 'int [*]'

    Yeah, I did very little arg validation.


    I see two further problems.

    What are they?


    With some stats you will have to set a
    minimum for N, but the first problem is just an incorrect index.

    BTW, when I was starting out, I'd give my right arm for gcc's -fsanitize=undefined and/or valgrind.


    I just tried -fsanitize=undefined and got that error. Is that new in gcc?

    valgrind is too hardcore for me (for the hobby C programs I write anyway).

    my new compile string is:
    $ gcc -Wall -Wextra -O3 -fsanitize=undefined mmv2.c -o mmv2 -lm


    Thanks for looking into it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to DFS on Thu Jun 13 09:54:46 2024
    DFS <nospam@dfs.com> writes:

    On 6/12/2024 7:36 PM, Ben Bacarisse wrote:
    DFS <nospam@dfs.com> writes:

    Same C program I just made a post about 'undefined behavior' on.

    I just noticed I get "stack smashing detected" only when I run the program >>> using a dataset of 75+ consecutive integers.

    set of 2 to 74 consecutive values: no problem.
    set of random values of any size: no problem.
    75+ consecutive values: problem

    Any easy way to find out what's causing this issue (probably a buffer
    overflow)?
    I compiled using -fsanitize=undefined and at runtime I get:
    $ ./dfs 70 -c
    70 Consecutive:
    No commas : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
    23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
    46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    69 70
    dfs.c:126:18: runtime error: index 70 out of bounds for type 'int [*]'
    ...
    Line 126:
    if(nums[i]-nums[i+1]!=0) {ucnt=1;} else {ucnt++;}
    nums is a VLA declared int nums[N];

    int nums[N] is OK isn't it, if I'm not running huge datasets?

    or should you always malloc:
    int *nums = malloc(N * sizeof(int));

    No, VLAs are fine, particularly for moderate sizes. They are now
    optional (post C11) but they won't be going away from gcc.

    and i runs from 0 to i < N (70 in
    this run). When i == 69 (the max) nums[i+1] is undefined (it's out of
    bounds).

    Good catch. Fixed.

    The code worked even with that bug - it always correctly identifies the mode(s), according to that website. But I probably got lucky and the
    mode(s) weren't the last data point.

    That's the trouble with undefined behaviour -- the desired behaviour is
    a possibility. If you always got an error, or at least the wrong
    result, you would have spotted this sooner.

    For this type of program there are loads of programming languages that
    either make this sort of slip either impossible or that will catch it at runtime.

    If I run
    $ ./dfs 1 -c
    1 Consecutive:
    No commas : 1
    dfs.c:126:18: runtime error: index 1 out of bounds for type 'int [*]'
    dfs.c:161:14: runtime error: index -1 out of bounds for type 'int [*]'
    dfs.c:162:32: runtime error: index 1 out of bounds for type 'int [*]'

    Yeah, I did very little arg validation.

    I see two further problems.

    What are they?

    I was meaning the two extra errors reported above -- on lines 161 and 162.


    With some stats you will have to set a
    minimum for N, but the first problem is just an incorrect index.
    BTW, when I was starting out, I'd give my right arm for gcc's
    -fsanitize=undefined and/or valgrind.

    I just tried -fsanitize=undefined and got that error. Is that new in
    gcc?

    New-ish.

    valgrind is too hardcore for me (for the hobby C programs I write
    anyway).

    What does "too hardcore" mean? It's very simple to use and catches more problems than gcc's runtime checks can. Compile with -g (so you get
    line number information) and then run under valgrind:

    $ gcc -g dfs.c -lm
    $ valgrind ./a.out 70
    ...
    ==327920== Conditional jump or move depends on uninitialised value(s) ==327920== at 0x484EF3A: strcat (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==327920== by 0x109E57: main (dfs.c:123)
    ==327920==
    ==327920== Conditional jump or move depends on uninitialised value(s) ==327920== at 0x484EF47: strcat (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==327920== by 0x109E57: main (dfs.c:123)
    ==327920==
    ==327920== Conditional jump or move depends on uninitialised value(s) ==327920== at 0x109E83: main (dfs.c:126)
    ==327920==

    It finds the previous error and another one. mode is uninitialised, so
    the strcat call on line 123 is undefined.

    Thanks for looking into it.

    You are most welcome.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Malcolm McLean on Fri Jun 14 04:06:21 2024
    On 2024-06-13, Malcolm McLean <malcolm.arthur.mclean@gmail.com> wrote:
    On 13/06/2024 09:54, Ben Bacarisse wrote:

    valgrind is too hardcore for me (for the hobby C programs I write
    anyway).

    What does "too hardcore" mean? It's very simple to use and catches more
    problems than gcc's runtime checks can. Compile with -g (so you get
    line number information) and then run under valgrind:


    valgrind is my favourite little utility. It's easy to use, and flushes
    out bugs very effectively. Unfotunately the Mac won't let me run it

    That's one of the benefits of writing cross-platform. Not every bug
    can be flushed out on every platform, whether by circumstances/fluke
    or availability of tooling (including from the toolchain or external).

    A program that run son Linux and Mac, and is checked with Valgrind on
    Linux, gives me a bit more confidence than a Mac-only similar program.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)