On kernel 2.6.29-0.258.rc8.git2.fc11.i686.PAE, I get an error from systemtap.base/overload.exp. I distilled the triggering script down to the following: # stap -e 'global k; probe begin { k["foo"] = 0 }' --vp 0002 Running make -C "/lib/modules/2.6.29-0.258.rc8.git2.fc11.i686.PAE/build" M="/tmp/stapQJkCVd" modules >/dev/null cc1: warnings being treated as errors /tmp/stapQJkCVd/stap_f59c71419a2c37ad1f014c89e1bd68e4_372.c: In function ‘probe_1383’: /usr/src/kernels/2.6.29-0.258.rc8.git2.fc11.i686.PAE/arch/x86/include/asm/string_32.h:75: error: array subscript is above array bounds make[1]: *** [/tmp/stapQJkCVd/stap_f59c71419a2c37ad1f014c89e1bd68e4_372.o] Error 1 make: *** [_module_/tmp/stapQJkCVd] Error 2 Pass 4: compiled C into "stap_f59c71419a2c37ad1f014c89e1bd68e4_372.ko" in 1310usr/1370sys/7652real ms. Pass 4: compilation failed. Try again with another '--vp 0001' option. Running rm -rf /tmp/stapQJkCVd The generated code is: 160 (void) 161 ({ 162 c->last_stmt = "identifier 'k' at <input>:1:25"; 163 l->__tmp2 = ((int64_t)0LL); 164 { int rc = _stp_map_set_si (global.s_k, "foo", l->__tmp2); if (unlikely(rc)) { c->last_error = "Array overflow, check MAXMAPENTRIES"; goto out; }}; 165 ((int64_t)0LL); 166 }); And the relevant excerpt from asm/string_32.h: 51 static __always_inline void *__constant_memcpy(void *to, const void *from, 52 size_t n) 53 { 54 long esi, edi; 55 if (!n) 56 return to; 57 58 switch (n) { [...] 73 case 5: 74 *(int *)to = *(int *)from; 75 *((char *)to + 4) = *((char *)from + 4); 76 return to; The important factor seems to be the length of the key = 3. Keys of length 2 also show the same error on line 75. Lengths 1 or 4+ seem to have no issue. The same kernel on x86_64 works fine.
Seems the problem is irrelevant to kernel, but gcc version. I can reproduce it on 2.6.27.9-159.fc10.i686 using gcc 4.3.2. But it can works fine on gcc 4.1.2 and 3.4.6. Maybe the difference of compiler optimization cause the problem. Related gcc bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38480 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37861
I'm using rawhide's gcc-4.4.0-0.23.i586.
(In reply to comment #2) > I'm using rawhide's gcc-4.4.0-0.23.i586. Please check the compiler using the example code in gcc bug38480 foo.c unsigned short foobar; int array[100]; void g(unsigned short j) { if (j < 100) array[j]++; } void f() { int i = foobar; if (i >= 100) g(foobar); } # gcc -O3 -Wall -c foo.c In my machine RHEL5U3, outputs: $ gcc34 -O3 -Wall -c foo.c $ gcc -O3 -Wall -c foo.c $ gcc43 -O3 -Wall -c foo.c foo.c: In function ‘f’: foo.c:6: warning: array subscript is above array bounds foo.c:6: warning: array subscript is above array bounds And the results of executing example stap script are like above.
(In reply to comment #3) > (In reply to comment #2) > > I'm using rawhide's gcc-4.4.0-0.23.i586. > > Please check the compiler using the example code in gcc bug38480 Yep, that example fails with rawhide's gcc too. Subtle tweaks can make the bug go away, like changing the 'i' to unsigned. Do you see anything in our runtime with a similar pattern? I wonder if we can tweak our code somehow to get by this...
Created attachment 3846 [details] workaround for the bug Seems there is no runtime code following the pattern in testcase. The culprit is memcpy for x86_32. The built-in copy function maybe cause bogus warning when specific length string is provided. Give one workaround to get by __constant_memcpy.
How about having the runtime use strlcpy, like in translator-generated code and elsewhere?
Created attachment 3849 [details] Use strlcpy and strlcat Indeed, using the built-in kernel functions seems to be the best route, and it does eliminate the error for me. Please try this out and confirm that the problem is fixed.
(In reply to comment #7) > Created an attachment (id=3849) > Use strlcpy and strlcat commit 4aa2079a01a62ff27cbe90f5eca38137035d34a8