|
From: Sigurd S. <sig...@go...> - 2006-01-18 13:06:25
|
Hi everyone!
Running valgrind-3.1.0 on my system with any executable always lead up to the
following error. I'm using the compiler option -fprefetch-loop-arrays. Maybe
that is a problem?
If you need more information feel free to mail me. If it is stupid to report
this, then please let me know.
Sigurd Schneider
But now read yourself:
Valgrind outputs:
==3392== Memcheck, a memory error detector.
==3392== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==3392== Using LibVEX rev 1471, a library for dynamic binary translation.
==3392== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==3392== Using valgrind-3.1.0, a dynamic binary instrumentation framework.
==3392== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==3392== For more details, rerun with: -v
==3392==
vex x86->IR: unhandled instruction bytes: 0xF 0xD 0x48 0x4
==3392== Your program just tried to execute an instruction that Valgrind
==3392== did not recognise. There are two possible reasons for this.
==3392== 1. Your program has a bug and erroneously jumped to a non-code
==3392== location. If you are running Memcheck and you just saw a
==3392== warning about a bad jump, it's probably your program's fault.
==3392== 2. The instruction is legitimate but Valgrind doesn't handle it,
==3392== i.e. it's Valgrind's fault. If you think this is the case or
==3392== you are not sure, please let us know.
==3392== Either way, Valgrind will now raise a SIGILL signal which will
==3392== probably kill your program.
==3392==
==3392== Process terminating with default action of signal 4 (SIGILL)
==3392== Illegal opcode at address 0x400F7C2
==3392== at 0x400F7C2: _dl_important_hwcaps (in /lib/ld-2.3.6.so)
==3392== by 0x4004E16: _dl_init_paths (in /lib/ld-2.3.6.so)
==3392== by 0x40022EB: dl_main (in /lib/ld-2.3.6.so)
==3392== by 0x400F182: _dl_sysdep_start (in /lib/ld-2.3.6.so)
==3392== by 0x4001610: _dl_start (in /lib/ld-2.3.6.so)
==3392== by 0x40007D6: (within /lib/ld-2.3.6.so)
==3392==
==3392== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==3392== malloc/free: in use at exit: 0 bytes in 0 blocks.
==3392== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==3392== For counts of detected errors, rerun with: -v
==3392== No malloc'd blocks -- no leaks are possible.
Disassembling shows the following code:
0x0000f7b4 <_dl_important_hwcaps+612>: mov $0x1,%esi
0x0000f7b9 <_dl_important_hwcaps+617>: shl %cl,%esi
0x0000f7bb <_dl_important_hwcaps+619>: test %esi,%esi
0x0000f7bd <_dl_important_hwcaps+621>: je 0xf80e
<_dl_important_hwcaps+702>
0x0000f7bf <_dl_important_hwcaps+623>: mov 0xffffffdc(%ebp),%eax
0x0000f7c2 <_dl_important_hwcaps+626>: prefetchw 0x4(%eax) <---- here
0x0000f7c6 <_dl_important_hwcaps+630>: prefetchw 0x44(%eax)
0x0000f7ca <_dl_important_hwcaps+634>: prefetchw 0x84(%eax)
0x0000f7d1 <_dl_important_hwcaps+641>: prefetchw 0xc4(%eax)
0x0000f7d8 <_dl_important_hwcaps+648>: prefetchw 0x104(%eax)
---Type <return> to continue, or q <return> to quit---
0x0000f7df <_dl_important_hwcaps+655>: prefetchw 0x144(%eax)
0x0000f7e6 <_dl_important_hwcaps+662>: dec %esi
0x0000f7e7 <_dl_important_hwcaps+663>: test %esi,%edx
0x0000f7e9 <_dl_important_hwcaps+665>: je 0xf806
<_dl_important_hwcaps+694>
This code is within the ld-2.3.6.so lib of glibc-2.3.6. I compiled glibc
myself using gcc-3.4.5 with decent optimizations:
-O2 -fprefetch-loop-arrays -march=athlon-xp -mpreferred-stack-boundary=2
-fPIC
I'm using tls and ntpl only.
The function is compiled from the following source code:
(taken from glibc-2.3.6/sysdeps/generic/dl-sysdep.c)
/* Return an array of useful/necessary hardware capability names. */
const struct r_strlenpair *
internal_function
_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
size_t *max_capstrlen)
{
/* Determine how many important bits are set. */
unsigned long int masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask);
size_t cnt = platform != NULL;
size_t n, m;
size_t total;
struct r_strlenpair *temp;
struct r_strlenpair *result;
struct r_strlenpair *rp;
char *cp;
/* Count the number of bits set in the masked value. */
for (n = 0; (~((1UL << n) - 1) & masked) != 0; ++n)
if ((masked & (1UL << n)) != 0)
++cnt;
#ifdef USE_TLS
/* For TLS enabled builds always add 'tls'. */
++cnt;
#else
if (cnt == 0)
{
/* If we have platform name and no important capability we only have
the base directory to search. */
result = (struct r_strlenpair *) malloc (sizeof (*result));
if (result == NULL)
goto no_memory;
result[0].str = (char *) result; /* Does not really matter. */
result[0].len = 0;
*sz = 1;
return result;
}
#endif
/* Create temporary data structure to generate result table. */
temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
m = 0;
for (n = 0; masked != 0; ++n)
if ((masked & (1UL << n)) != 0)
{
temp[m].str = _dl_hwcap_string (n);
temp[m].len = strlen (temp[m].str);
masked ^= 1UL << n;
++m;
}
if (platform != NULL)
{
temp[m].str = platform;
temp[m].len = platform_len;
++m;
}
#ifdef USE_TLS
temp[m].str = "tls";
temp[m].len = 3;
++m;
#endif
assert (m == cnt);
/* Determine the total size of all strings together. */
if (cnt == 1)
total = temp[0].len + 1;
else
{
total = (1UL << (cnt - 2)) * (temp[0].len + temp[cnt - 1].len + 2);
for (n = 1; n + 1 < cnt; ++n)
total += (1UL << (cnt - 3)) * (temp[n].len + 1);
}
/* The result structure: we use a very compressed way to store the
various combinations of capability names. */
*sz = 1 << cnt;
result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
if (result == NULL)
{
#ifndef USE_TLS
no_memory:
#endif
_dl_signal_error (ENOMEM, NULL, NULL,
N_("cannot create capability list"));
}
if (cnt == 1)
{
result[0].str = (char *) (result + *sz);
result[0].len = temp[0].len + 1;
result[1].str = (char *) (result + *sz);
result[1].len = 0;
cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
*cp = '/';
*sz = 2;
*max_capstrlen = result[0].len;
return result;
}
/* Fill in the information. This follows the following scheme
(indeces from TEMP for four strings):
entry #0: 0, 1, 2, 3 binary: 1111
#1: 0, 1, 3 1101
#2: 0, 2, 3 1011
#3: 0, 3 1001
This allows the representation of all possible combinations of
capability names in the string. First generate the strings. */
result[1].str = result[0].str = cp = (char *) (result + *sz);
#define add(idx) \
cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
if (cnt == 2)
{
add (1);
add (0);
}
else
{
n = 1 << (cnt - 1);
do
{
n -= 2;
/* We always add the last string. */
add (cnt - 1);
/* Add the strings which have the bit set in N. */
for (m = cnt - 2; m > 0; --m)
if ((n & (1 << m)) != 0)
add (m);
/* Always add the first string. */
add (0);
}
while (n != 0);
}
#undef add
/* Now we are ready to install the string pointers and length. */
for (n = 0; n < (1UL << cnt); ++n)
result[n].len = 0;
n = cnt;
do
{
size_t mask = 1 << --n;
rp = result;
for (m = 1 << cnt; m > 0; ++rp)
if ((--m & mask) != 0)
rp->len += temp[n].len + 1;
}
while (n != 0);
/* The first half of the strings all include the first string. */
n = (1 << cnt) - 2;
rp = &result[2];
while (n != (1UL << (cnt - 1)))
{
if ((--n & 1) != 0)
rp[0].str = rp[-2].str + rp[-2].len;
else
rp[0].str = rp[-1].str;
++rp;
}
/* The second have starts right after the first part of the string of
corresponding entry in the first half. */
do
{
rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1;
++rp;
}
while (--n != 0);
/* The maximum string length. */
*max_capstrlen = result[0].len;
return result;
}
|