2011-09-30 34 views
3

我正在爲m68k目標上的嵌入式系統開發一些舊的源代碼,並且在調用gcvtf來格式化顯示的浮點數時,有時會看到大量內存分配請求。我可以通過編寫我自己的替代例程來解決這個問題,但是錯誤的性質讓我非常好奇,因爲它只發生在堆開始於某個地址或某個地址之上時,並且如果我破解.ld鏈接器腳本或刪除任何一組全局變量(放置在我的內存映射中的堆之前),這些全局變量的總和足夠大,以便堆開始在神祕的關鍵地址之下。因此,我認爲我會在我使用的編譯器版本(m68k-elf-gcc 3.3.2)的gcc源代碼中查找。我在http://gcc.petsads.us/releases/gcc-3.3.2/下載了這個版本的源代碼,但是我找不到gcvt或gcvtf的定義。當我尋找它,grep的只是發現了一些文件和.h引用,但不是定義:gcvt或gcvtf在gcc源代碼中定義的位置?

$ find | xargs grep gcvt 
./gcc/doc/gcc.info:  C library functions `ecvt', `fcvt' and `gcvt'. Given va 
lid 
./gcc/doc/trouble.texi:library functions @code{ecvt}, @code{fcvt} and @code{gcvt 
}. Given valid 
./gcc/sys-protos.h:extern char *     gcvt(double, int, char *); 

所以,凡在源代碼實際上這個函數?或者我下載了完全錯誤的東西?

由於項目的穩定性和測試的考慮,我不想改變這個項目使用最新的gcc,就像我說的,我可以通過編寫自己的格式化例程來解決這個問題,但這種行爲是非常讓我感到困惑,如果我沒有發現它爲什麼這麼奇怪,它會磨礪我的大腦。

回答

3

Wallyk是正確的,這是在C庫而不是編譯器中定義的。但是,GNU C庫(幾乎總是)僅用於Linux編譯器和發行版。您的編譯器,作爲「裸機」編譯器,幾乎可以肯定地使用Newlib C庫。

Newlib的主網站是:http://sourceware.org/newlib/,這個特定的功能在newlib/libc/stdlib/efgcvt.c文件中定義。這些源代碼很長時間都非常穩定,所以(除非這是一個bug的結果),因爲目前的源代碼與編譯器使用的代碼沒有太大差別,所以機會相當好。

與GNU C源代碼一樣,我沒有看到任何可能會導致您看到的奇怪的東西,但最終都是圍繞基本的sprintf例程的一堆包裝。

+0

謝謝!我找到了我使用的newlib版本的源代碼(1.11.0),並且gcvt實際上調用了一個函數_dtoa_r,它調用了一些分配函數。我很確定這種奇怪的行爲在那裏。 –

+0

@SamSkuce:是的,這聽起來像是正確的地方。 –

2

它在GNU C庫中爲glibc/misc/efgcvt.c。爲了節省您的一些麻煩,該函數的代碼是:

char * 
__APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf) 
    FLOAT_TYPE value; 
    int ndigit; 
    char *buf; 
{ 
    sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", MIN (ndigit, NDIGIT_MAX), value); 
    return buf; 
} 

爲獲得glibc的方向是here

+0

謝謝!當然,這並不包含任何能夠解釋堆分配怪異的東西。哦,我現在會把我的好奇心放在後門上,在項目完成之後再看看它。 –

+0

正如我在我的回答中指出的那樣,GNU C將是Linux編譯器的正確答案,但這似乎是一個裸機編譯器(按照目標中的「-elf-」),因此將使用Newlib。 –