Re: Bug#592142: ctemplate: FTBFS on sparc: 10 of 20 tests failed
On Sun, Aug 08, 2010 at 10:27:05AM +1000, Mark Purcell wrote:
> On Sunday 08 August 2010 04:42:21 Cyril Brulebois wrote:
> > | 10 of 20 tests failed
>
> KiBi,
>
> Thanks for the report.
>
> This is a pain as we have turned on the check tests target in -2, and it is only failing on sparc with a bus error, so I suspect it isn't the code, but rather the stress of the tests. I have forwarded to google to see if they have a view.
>
> Should I disable tests for sparc only?
>
> Mark
This turned out to be fairly easy to track down. The memory for
TemplateDictionary class is allocated in src/template_dictionary.cc
using AllocAlign, with the alignment set to sizeof(void *). In this
case it is not sufficient, because, for example, TemplateDictionary
has a name_ field, which is a TemplateString, which, in turn has an
id_ field, which is u_int64_t. The 8-byte size of id_ imposes 8-byte
alignment requirement on objects of all parent classes, including
TemplateDictionary, and in this case it's not happening, as
sizeof(void *) is 4 on sparc. So, when id_ needs to be zeroed out
(which happens when it's set to kIllegalId), compiler uses clrx (clear
extended word) instructions, which operates on an 8-byte memory
region, which it expects to be 8-byte aligned.
I've noticed that arena.h already has a kDefaultAlignment variable
which is set correctly depending on the architecture, so I've cooked
up a simple patch (attached) to use it instead of hardcoded
sizeof(void *) for allocations in template_dictionary.cc. With this
patch the package builds fine in up-to-date sid.
By the way, according to http://code.google.com/p/google-ctemplate/
the upstream address is google-ctemplate at googlegroups dot com.
Best regards,
--
Jurij Smakov jurij@wooyd.org
Key: http://www.wooyd.org/pgpkey/ KeyID: C99E03CC
diff -aur a/src/template_dictionary.cc b/src/template_dictionary.cc
--- a/src/template_dictionary.cc 2010-04-08 20:42:46.000000000 +0100
+++ b/src/template_dictionary.cc 2010-08-08 20:27:55.000000000 +0100
@@ -87,9 +87,8 @@
arena_->Free(p, n * sizeof(T));
}
-// TODO(csilvers): sizeof(void*) may be too big. But is probably ok.
/*static*/ template<class T> const int ArenaAllocator<T>::kAlignment =
- (1 == sizeof(T) ? 1 : sizeof(void*));
+ (1 == sizeof(T) ? 1 : BaseArena::kDefaultAlignment);
// ----------------------------------------------------------------------
// TemplateDictionary::map_arena_init
@@ -123,7 +122,7 @@
if (*dict != NULL)
return;
// Placement new: construct the map in the memory used by *dict.
- void* buffer = arena_->AllocAligned(sizeof(**dict), sizeof(void*));
+ void* buffer = arena_->AllocAligned(sizeof(**dict), BaseArena::kDefaultAlignment);
new (buffer) T(arena_);
*dict = reinterpret_cast<T*>(buffer);
}
@@ -138,7 +137,7 @@
}
inline TemplateDictionary::DictVector* TemplateDictionary::CreateDictVector() {
- void* buffer = arena_->AllocAligned(sizeof(DictVector), sizeof(void*));
+ void* buffer = arena_->AllocAligned(sizeof(DictVector), BaseArena::kDefaultAlignment);
// Placement new: construct the vector in the memory used by buffer.
new (buffer) DictVector(arena_);
return reinterpret_cast<DictVector*>(buffer);
@@ -149,7 +148,7 @@
UnsafeArena* arena,
TemplateDictionary* parent_dict,
TemplateDictionary* template_global_dict_owner) {
- void* buffer = arena->AllocAligned(sizeof(TemplateDictionary), sizeof(void*));
+ void* buffer = arena->AllocAligned(sizeof(TemplateDictionary), BaseArena::kDefaultAlignment);
// Placement new: construct the sub-tpl in the memory used by tplbuf.
new (buffer) TemplateDictionary(name, arena, parent_dict,
template_global_dict_owner);
Reply to: