Bug 10001 - 32-bit map error "array subscript is above array bounds"
Summary: 32-bit map error "array subscript is above array bounds"
Status: RESOLVED FIXED
Alias: None
Product: systemtap
Classification: Unclassified
Component: runtime (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-03-25 01:58 UTC by Josh Stone
Modified: 2009-03-26 18:02 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
workaround for the bug (494 bytes, patch)
2009-03-26 07:38 UTC, Wenji Huang
Details | Diff
Use strlcpy and strlcat (380 bytes, patch)
2009-03-26 16:28 UTC, Josh Stone
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Josh Stone 2009-03-25 01:58:38 UTC
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.
Comment 1 Wenji Huang 2009-03-25 08:19:33 UTC
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
Comment 2 Josh Stone 2009-03-25 18:01:59 UTC
I'm using rawhide's gcc-4.4.0-0.23.i586.
Comment 3 Wenji Huang 2009-03-26 01:57:22 UTC
(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.
Comment 4 Josh Stone 2009-03-26 05:39:58 UTC
(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...
Comment 5 Wenji Huang 2009-03-26 07:38:21 UTC
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.
Comment 6 Frank Ch. Eigler 2009-03-26 12:41:37 UTC
How about having the runtime use strlcpy, like in translator-generated code and
elsewhere?
Comment 7 Josh Stone 2009-03-26 16:28:09 UTC
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.
Comment 8 Josh Stone 2009-03-26 18:02:37 UTC
(In reply to comment #7)
> Created an attachment (id=3849)
> Use strlcpy and strlcat

commit 4aa2079a01a62ff27cbe90f5eca38137035d34a8