Deutsch English Français Italiano |
<877cetz0h5.fsf@bsb.me.uk> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Ben Bacarisse <ben@bsb.me.uk> Newsgroups: comp.lang.c Subject: Re: "stack smashing detected" Date: Thu, 13 Jun 2024 09:54:46 +0100 Organization: A noiseless patient Spider Lines: 113 Message-ID: <877cetz0h5.fsf@bsb.me.uk> References: <666a10d3$0$973$882e4bbb@reader.netnews.com> <87cyolzqb2.fsf@bsb.me.uk> <666a3d62$0$981$882e4bbb@reader.netnews.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Thu, 13 Jun 2024 10:54:47 +0200 (CEST) Injection-Info: dont-email.me; posting-host="f081befcc253f0e66a7d8b4dfbce31ac"; logging-data="2302162"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/GSikcDvrx7Jt6xD5N7mk9Hec+85aVAk0=" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:W/npq8SeN8kYNkYcsWQQEVinGQ4= sha1:L+P6QborqL7El8AVnDaAo6ZOR5A= X-BSB-Auth: 1.2b43113e34b3fa766bc4.20240613095446BST.877cetz0h5.fsf@bsb.me.uk Bytes: 5037 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.