Как перегрузить операторы создания/удаления в VxWorks 7 с помощью компилятора Gnu

Я пытаюсь создать проект изображения VxWorks7 (VIP), который включает мое приложение, которое перегружает новые и удаляемые. Когда я создаю VIP и приложение отдельно с приложением в качестве загружаемого модуля ядра (DKM), оно создается и работает нормально, загружая VIP на целевом устройстве и отдельно загружая DKM приложения с помощью Workbench4. Однако, если я попытаюсь собрать VIP и DKM вместе как один загрузочный VIP, я получаю несколько ошибок определения для новых и удаляющих операторов из Workbench во время сборки следующим образом:

C:/BW/Vehicle/builds/cx20X0Up32BitDebugVsb/krnl/gnu_standard\libgnucplus.a(_x_gnu_delaop.o): In function `operator delete[](void*)':
(.text+0x0): multiple definition of `operator delete[](void*)'
C:/BW/Vehicle/builds/Vehicle/cx20X0Up32BitDebugVsb_SANDYBRIDGEgnu/Vehicle_partialImage/Debug/Vehicle_partialImage.o:C:/BW/Alcatraz/Vehicle/src/IRL/Util/heap.cpp:886: first defined here
C:/BW/Vehicle/builds/cx20X0Up32BitDebugVsb/krnl/gnu_standard\libgnucplus.a(_x_gnu_delop.o): In function `operator delete(void*)':
(.text+0x0): multiple definition of `operator delete(void*)'
C:/BW/Vehicle/builds/Vehicle/cx20X0Up32BitDebugVsb_SANDYBRIDGEgnu/Vehicle_partialImage/Debug/Vehicle_partialImage.o:C:/BW/Alcatraz/Vehicle/src/IRL/Util/heap.cpp:841: first defined here
C:/BW/Vehicle/builds/cx20X0Up32BitDebugVsb/krnl/gnu_standard\libgnucplus.a(_x_gnu_newaop.o): In function `operator new[](unsigned int)':
(.text+0x0): multiple definition of `operator new[](unsigned int)'
C:/BW/Vehicle/builds/Vehicle/cx20X0Up32BitDebugVsb_SANDYBRIDGEgnu/Vehicle_partialImage/Debug/Vehicle_partialImage.o:C:/BW/Alcatraz/Vehicle/src/IRL/Util/heap.cpp:813: first defined here
C:/BW/Vehicle/builds/cx20X0Up32BitDebugVsb/krnl/gnu_standard\libgnucplus.a(_x_gnu_newop.o): In function `operator new(unsigned int)':
(.text+0x0): multiple definition of `operator new(unsigned int)'
C:/BW/Alcatraz/Vehicle/builds/Vehicle/cx20X0Up32BitDebugVsb_SANDYBRIDGEgnu/Vehicle_partialImage/Debug/Vehicle_partialImage.o:C:/BW/Alcatraz/Vehicle/src/IRL/Util/heap.cpp:808: first defined here
collect2.exe: error: ld returned 1 exit status 

Служба поддержки WindRiver предложила решение сделать следующие объявления в исходном файле, где операторы new и delete перегружены. Предполагается, что это сигнализирует компилятору/компоновщику опустить библиотечную версию операторов new/del.

int ___x_gnu_newaop_o = 1;
int ___x_gnu_newop_o = 1;
int ___x_gnu_delaop_o = 1 ;
int ___x_gnu_delop_o = 1;

Выполняя это, я по-прежнему получаю те же множественные определенные ошибки, что и выше, и служба поддержки WindRiver не имеет никаких жизнеспособных предложений. Кто-нибудь пробовал перегружать глобальные ::new и ::delete в VxWorks7 с помощью компилятора Gnu?

Вот ссылка на проблему в службе поддержки WindRiver 66370. Не уверен, что он имеет публичный доступ.


person JonN    schedule 10.01.2017    source источник


Ответы (2)


Я столкнулся с похожей ситуацией с переопределением функций malloc/free для целей отладки. Возможно, мое решение грубое, но простое и эффективное: я просто переименовал стандартные функции в «malloc_original» и «free_original». Таким образом, все вызовы malloc и free были связаны только с новой реализацией, в то время как новые версии malloc и free при необходимости вызывали исходную функциональность. Вот как:

  1. Найдите библиотеку с оригинальной функциональностью. В вашем случае это libgnucplus.a
  2. Библиотека — это просто архив с объектами. Извлеките их с помощью ar -x libgnucplus.a
  3. Список символов в объектах, на которые жаловался компоновщик (_x_gnu_delaop.o, _x_gnu_delop.o и т. д.), используя nm objectName.o. Найдите имена операторов, они будут искажать имена
  4. Если объекты не экспортируют ничего, кроме нежелательных операторов, и вы не хотите сохранять исходную реализацию, можно создать libgnucplus.a из всех файлов obj, кроме этих, поэтому вы можете пропустить другие шаги.
  5. В противном случае запустите objcopy --redefine-sym operatorName__WithMangling=operatorNameOriginal__WithMangling objFile.o. Я делал это на чистом C-функциях, поэтому искажений не было, но я уверен, что искажения не будут большой помехой.
  6. Поместите измененные файлы obj обратно в lib: ar rvs libgnucplus.a objFile1.o objFile2.o ...
  7. Веселиться

Не отрицаю, этот подход достаточно грязен и имеет некоторые недостатки. Например, измененный набор инструментов подразумевает, что его обновление потребует повторного выполнения всех тех же шагов; во-вторых, разработчику, не знающему о ситуации (что не редкость в долгосрочных проектах), будет очень трудно разобраться в деталях. В моем случае он использовался для временной отладки проблем с памятью, так что никаких моральных аспектов не было :)

person nnovich-OK    schedule 12.01.2017

Оказывается, многократное определение после попытки обходного пути, предложенного Wind River, было связано с библиотеками с циклическими ссылками, а также с использованием обходного пути, указывающего все перегрузки, когда использовались только некоторые из них. Теперь я могу без проблем строить, используя следующее и не прибегая к модифицированной стандартной библиотеке, которую мы использовали ранее с VxWorks 6.x:

// ======== SPECIAL CASE NEW/DELETE OPERATOR OVERLOAD FOR GNU ========
// The following ___x_gnu_????.o global variable definitions are special
// case indicators to Gnu compiler when building the application into an
// integrated VIP (VxWorks Image Project).  They indicate which new and
// delete operators are being overloaded.  Doing this avoids a multiple
// definition build error for new/delete operators.  This multiple
// definition error is only an issue when building application as an
// integrated VIP and not when app is downloaded separate from VIP as a
// Downloadable Kernel Module (DKM).  It is important to only include
// ___x_gnu_????_o variables for the specific operators being
// overloaded.  Defining a ___x_gnu_????_o variable for an operator that
// is not actually overloaded will cause a multiple define error also.
// This solution to overloading new/delete was obtained directly from
// Wind River support and is described in case #66370 and as of this
// date is not described anywhere in Wind River documentation.
// link to case #66370 below. -- 2017Jan18jdn
//
// https://windriver.force.com/support/apex/CaseReadOnly?id=5001600000xKkTYAA0
int ___x_gnu_newaop_o = 1;      // Indicates overload of new [] operator
int ___x_gnu_newop_o = 1;       // Indicates overload of new operator
int ___x_gnu_delaop_o = 1 ;     // Indicates overload of delete [] operator
int ___x_gnu_delop_o = 1;       // Indicates overload of delete operator
person JonN    schedule 11.02.2017