0

我試圖創建一個VxWorks7形象工程(VIP),包括我的應用程序,它重載new和delete。當我使用應用程序作爲可下載的內核模塊(DKM)單獨構建VIP和應用程序時,它可以通過在目標上引導VIP並使用Workbench4單獨下載App DKM來構建和運行。但是,如果我嘗試共同打造的VIP和DKM作爲一個可啓動的VIP我得到多個定義了新的錯誤,並在生成過程中刪除工作臺運營商如下:如何重載新/刪除的VxWorks 7運營商GNU編譯器

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/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公司的支持一直沒有任何可行的建議。有沒有人有過嘗試使用Gnu編譯器在VxWorks7中重載global :: new和:: delete的經驗?

這裏是鏈接到這個問題上WindRiver的支持66370。不確定它是否具有公共訪問權限。

回答

0

在嘗試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 
0

我碰到與重新定義的malloc/free函數進行調試類似的情況。也許,我的解決方案很粗糙,但它很簡單高效:我只是將標準函數重命名爲「malloc_original」和「free_original」。因此,所有對malloc和free的調用都只與新的實現相關聯,而新版本的malloc和free會在必要時調用原始功能。方法如下:

  1. 查找具有原始功能的庫。在你的情況下,其libgnucplus.a
  2. 圖書館只是對象檔案。用ar -x libgnucplus.a提取它們
  3. 在對象中列出符號,鏈接器正在使用nm objectName.o抱怨(_x_gnu_delaop.o,_x_gnu_delop.o等)。查找運營商的名字,他們都會有一些name mangling
  4. 如果對象導出什麼,除了不需要運營商和你不希望保留原始的實現,應該確定從這些以外所有OBJ文件創建libgnucplus.a,所以你可以跳過其他步驟
  5. 否則運行objcopy --redefine-sym operatorName__WithMangling=operatorNameOriginal__WithMangling objFile.o。我在純粹的C函數上做了這個,所以沒有發生混亂,但我確信,混亂不會是一個很大的障礙。
  6. 認沽修改OBJ文件放回LIB:ar rvs libgnucplus.a objFile1.o objFile2.o ...
  7. 玩得開心

我不否認,這種做法是非常髒,有一些缺點。例如修改過的工具鏈暗示,它的升級將需要重新執行所有相同的步驟;另一個原因是開發人員沒有意識到這種情況(在持久項目中這種情況並非罕見),因此確實很難找出細節。在我的情況下,它用於臨時調試內存問題,所以沒有涉及到道德方面:)