У меня есть следующий код:
#include <iostream>
#include <stdint.h>
#include <stdio.h>
// Structure from 3rd party that cannot be modified
typedef struct {
uint32_t flags;
uint32_t len;
uint8_t padding[120];
} mystruct_t __attribute__ ((aligned(128)));
// Classes used internally
class Matcher {
};
class MatcherEQ : public Matcher {
mystruct_t _bson;
};
Matcher* factory() {
return new MatcherEQ();
}
// Structure used for C/C++ interface
typedef void* Match_t;
// Pure C API
extern "C" {
void CreateMatch(Match_t *pm) {
*pm = NULL;
Matcher *b = factory();
*pm = (Match_t)b;
}
}
int main(void) {
// C style code
puts("C\n");
Match_t m;
CreateMatch(&m);
// C++ code
std::cout << "C++" << std::endl;
Matcher *pm = factory();
return 0;
}
Я скомпилировал его с внутренней цепочкой инструментов моей рабочей среды, которая использует g cc 4.3.2 + Sanitizer. Сгенерированная командная строка выглядит следующим образом:
g++ -fsanitize=undefined -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=address -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wnull-dereference -Wno-unused-local-typedefs -Wno-deprecated -Wformat=2 -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++98 -DDISABLE_MEMORY_ALLOCATORS=1 -march=k8 -pipe -fPIC -fno-strict-aliasing -Wall -Wpointer-arith -Wshadow -Wcast-align -Wimplicit -fno-tree-sra -g -Wno-write-strings -Wno-cast-qual -g3 -O0 -D__UNIX64__ -D__64BIT__ -D__LINUX64__ -D_LP64 -DSLES_10 alignissue.cpp
При ее запуске я получаю следующий вывод:
C
../Sources/Tests/C/alignissue.cpp:48: runtime error: store to misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
01 00 00 62 be be be be be be be be be be be be be be be be be be be be be be be be be be be be
^
../Sources/Tests/C/alignissue.cpp:41:7: runtime error: member access within misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
01 00 00 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
../Sources/Tests/C/alignissue.cpp:41:7: runtime error: member access within misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
01 00 00 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d8 c3 12 a3
^
C++
=================================================================
==21777==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 384 byte(s) in 1 object(s) allocated from:
#0 0x7f4aa347500f in operator new(unsigned long) (../../libasan.so+0x10c00f)
#1 0x403d05 in factory() ../Sources/Tests/C/alignissue.cpp:48
#2 0x40402e in main ../Sources/Tests/C/alignissue.cpp:75
#3 0x7f4aa19f5c35 in __libc_start_main (/lib64/libc.so.6+0x1ec35)
Direct leak of 384 byte(s) in 1 object(s) allocated from:
#0 0x7f4aa347500f in operator new(unsigned long) (../../libasan.so+0x10c00f)
#1 0x403d05 in factory() ../Sources/Tests/C/alignissue.cpp:48
#2 0x403e31 in CreateMatch ../Sources/Tests/C/alignissue.cpp:60
#3 0x403f17 in main ../Sources/Tests/C/alignissue.cpp:71
#4 0x7f4aa19f5c35 in __libc_start_main (/lib64/libc.so.6+0x1ec35)
SUMMARY: AddressSanitizer: 768 byte(s) leaked in 2 allocation(s).
Причина утечек памяти очевидна.
Но я Я хочу понять и исправить проблемы с неправильным адресом .
typedef void* Match_t
здесь, потому что в моей рабочей среде я могу экспортировать только чистые C API. Так что я нашел обходной путь для экспорта функций, работающих с классами C ++.
У меня также нет выбора для версии компилятора g cc: - (