




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、簡單的C 程序調(diào)試日志想了解更多請登陸中山大學新華學院This can be solved by letting the log class store astatic integer holding the stack depth.雖然仍有可能推斷出該調(diào)用鏈,輸出格式不到任何竭盡全力使用戶很容易這樣做。這是解決讓log類存儲靜態(tài)整數(shù)堆棧深度舉行。By converting the stack depth to an indentation the output can be formatted to show the call chain.通過轉(zhuǎn)換堆棧壓痕深度的一鏈的輸出的格式可以顯示呼叫。
2、Since it is stored in astatic member,each instance of the log class simply increments it in its constructor,and decrements it in its destructor.因為它是存儲在一個靜態(tài)成員,每個實例的log類的構(gòu)造簡單增量它,它和它的析構(gòu)遞減研究。Using this technique,the output becomes more readable:使用這種技術(shù),輸出變得更加清晰可辨:想了解更多請登陸中山大學新華學院論壇The logging statements
3、required to get the output above would be something like this:該記錄必須得到上面的輸出會是這樣的語句:Collapse Copy Code int bar()詮釋欄()(DEBUG_METHOD(bar);DEBUG_METHOD(酒吧);/Do bar logic/做酒吧邏輯return 1;返回1;)void foo()無效富()(DEBUG_METHOD(foo);DEBUG_METHOD(富);switch(bar()開關(guān)(巴()(case 0:案件0:/Do 0stuff,and return immediately/做0
4、的東西,并立即返回return;返回;case 1:案例一:/Do 1stuff and continue/做第一件東西,并繼續(xù)break;打破;default:默認值:throw std:exception(failed);扔性?。豪?失敗);)/additional logic/額外的邏輯)int main(int/*argc*/,char*/*argv*/)國際主要(詮釋/*argc*/,焦炭*/*argv中獲取*/)(DEBUG_METHOD(main);DEBUG_METHOD(主);foo();美孚();return 0;返回0;)Notice that regardless o
5、f how or where the foo method exists,the log output is the same as the exit output is written on scope completion of the log object instanciated at the top of every method using the DEBUG_METHOD macro.請注意,不論如何或在foo法存在,日志輸出是輸出相同的出口范圍是寫在完成log對象的實例化以后,在使用前法每DEBUG_METHOD宏。Execution time執(zhí)行時間In this debug
6、 log,it is also possible to get the method exit output to include the execution time of the logged method(including any of its children).This is done by storing the current time when the log object is instanciated,and then subtracting this from the time of destruction.在此調(diào)試日志,也有可能退出該方法得到的輸出包括其子女的執(zhí)行時間
7、的記錄方法(包括任何)。這是通過存儲當前的時候log對象實例化,然后減去這從毀滅的時間。There are many ways to get atimestamp in C+,Ive decided to go with the clock()method found in time.h.As including that perticular header might not be part of the logged application,it is possible to disable the timing completely,or rather,it has to be expl
8、icitly enabled by defining DEBUG_LOG_ENABLE_TIMING.有很多方法可以得到一個在C+時間戳,我決定去與clock()中找到方法time.h應用。由于包括perticular頭可能沒有被記錄的一部分,它可以禁用時間完全,或者更確切地說,它必須明確地啟用界定DEBUG_LOG_ENABLE_TIMING。This yields aconstructor/destructor pair for the log class that looks like this:這就產(chǎn)生一個構(gòu)造/析構(gòu)函數(shù)為對log類,這是這樣的:Collapse Copy Code i
9、nt log:indentation=0;詮釋日志:縮進=0;std:ostream*log:stream=&std:cout;性?。簅stream中*日志:流=&標準:法院;log:log(const std:string&ctx)日志:日志(常量標準:字符串和環(huán)磷酰胺):context(ctx):背景(環(huán)磷酰胺)#ifdef DEBUG_LOG_ENABLE_TIMING#ifdef DEBUG_LOG_ENABLE_TIMING,start_time(clock(),start_time(時鐘()#endif#endif(write_indentation();write_indenta
10、tion();*stream-context std:endl;*流-中性?。憾鞯拢?indentation;+縮進;)log:log()日志:?日志()(-indentation;-壓痕;write_indentation(std:uncaught_exception()?*:);write_indentation(標準:uncaught_exception()?*:);*stream-context;*流-背景;#ifdef DEBUG_LOG_ENABLE_TIMING#ifdef DEBUG_LOG_ENABLE_TIMING*streamin(double)(clock()-star
11、t_time)/CLOCKS_PER_SEC)s;*流中的(雙)(時鐘()-start_time)/CLOCKS_PER_SEC)S型;#endif#endif*stream std:endl;*流性?。憾鞯?;)The std:ostream*log:stream is another static member holding areference to the output method,by default set to std:cout.在std:ostream*log:stream是另一種靜態(tài)成員持有方法引用到輸出,通過對默認設置std:cout。Indentation by sta
12、ck depth is written using the private helper method write_indentation(),which simply uses the value stored in the static indentation variable to write acouple of spaces to log:stream.壓痕深度的堆棧書,用的私人輔助方法write_indentation()它只是使用了靜態(tài)的值存儲indentation變量寫一夫婦向空間log:stream。Exception logging異常記錄When an exception
13、 is thrown,its good to know how it bubbled up the call stack,especially if it is one that is not going to be caught at all by the application(in the case of an unexpected exception).當異常被拋出,其良好知道如何調(diào)用堆棧向上冒泡,尤其是如果它是一個不會意外的異常被捕獲在所有的應用程序的案件(在)。A neat function included in the STL is the std:uncaught_excep
14、tion()which returns true if theres currently an uncaught exception alive.一個整潔的STL函數(shù)是包含在std:uncaught_exception()它返回true,如果有未捕獲的異?,F(xiàn)為活著。In the destructor of the log class this is called to use an asterisk to indicate that the current method exited because of an exception(as shown in the code example ab
15、ove).在析構(gòu)函數(shù)的log類,這是要求使用星號顯示,目前上述方法退出因為有一個例外(例如在代碼中所示)。So in the previous application example,if the bar()method had returned 2for example,then the output would have looked like this instead(provided that the exception was caught and handeled in the main method):因此,在以前的應用程序的例子,如果bar()方法返回了例子2,那么輸出將有這個
16、樣子,而不是(前提是該異常被抓住的handeled的main方法):The*character is in this example indicating that when the foo()method completed,there was alive exception still uncaught,but as the main()method exit log is not preceded by a*,that exception must have been caught in that method.在*字符是在這個例子說明,當foo()方法完成,有一個例外仍然未捕獲的活,但
17、由于main()方法退出登錄不是前面有一個*,該異常必須是在該方法捕獲。Logging value of variables測井變量的值To get enough information to trouble shoot an issue,both the context(call chain)and the values of the relevant variables need to be logged.Preferrably,the logger should be able to log any type of value,to achieve this in a.NET langu
18、age would have been easy since all objects inherit from System.Object and atextual representation of the value can be retrieved using the ToString()method.C+does not offer such luxuries,but by using template programming it is possible to achieve something similar.為了獲得足夠的信息,麻煩拍攝一個問題,無論是上下文(調(diào)用鏈)及相關(guān)變量的
19、值必須被記錄。最好,記錄器應能記錄任何類型的價值,實現(xiàn)這個在。NET語文本來容易,因為所有的對象從繼承System.Object和價值的文字表述了可以檢索使用ToString()方法。C+并沒有提供這樣的奢侈,但通過使用模板編程就可以實現(xiàn)類似的東西。But logging value alone is not enough,the value has to have name as well and this could have been done by something like:但是,僅僅記錄值是不夠的,必須具有的價值,以及這名本來可以做的是這樣的:Collapse Copy Code
20、#define LOG_VARIABLE(name,value)log_variable(name,value);#定義LOG_VARIABLE(名稱,值)log_variable(名稱,值);template Tvoid log_variable(const std:string&name,const T&value)模板?無效log_variable(常量標準:字符串和名稱,常量?及價值)(std:cout name=value std:endl;性病:法院名字=價值性?。憾鞯?;)The annoying thing about this is that the programmer is
21、 forced to manually name the value when outputting it,which is redunant in most cases since the identifier being logged usually have aname anyway(the name of the variable).關(guān)于這惱人的是,程序員不得不手動的名字時,輸出它的價值,這是在大多數(shù)情況下redunant被記錄以來的標識符通常有一個名字反正(變量名稱)。To get around this problem,I used the#operator of C+s pre-
22、processor language,which will yield the name,rather than then value,of apassed parameter:為了解決這個問題,我用#參數(shù)運營商的C+的預處理器的語言,這將產(chǎn)生的名稱,而不是再通過價值,一:Collapse Copy Code#define DEBUG_VALUE_OF(variable)_debugLog.value_of(#variable,variable,false);#定義DEBUG_VALUE_OF(變量)(_debugLog.value_of(#變,變,假);)class log類日志(templ
23、ate class Tvoid value_of(const std:string&name,const T&value,const bool outputTypeInformation);模板類T無效value_of(常量標準:字符串和名稱,常量?及價值,常量布爾outputTypeInformation););template class Tvoid log:value_of(const std:string&name,const T&value,const bool outputTypeInformation)模板類T無效日志:value_of(常量標準:字符串和名稱,常量?及價值,常量
24、布爾outputTypeInformation)(write_indentation();write_indentation();*stream name;*流名稱;#ifdef DEBUG_LOG_ENABLE_TYPE_OUTPUT#ifdef DEBUG_LOG_ENABLE_TYPE_OUTPUT if(outputTypeInformation)如果(outputTypeInformation)(*stream(typeid(value).name();*流(typeid(值)。名稱();)#endif#endif*stream=valuestd:endl;*流=價值性?。憾鞯拢籹t
25、ream-flush();流刷新();)This allows the programmer to log variables and their values using this syntax:這使得程序員登錄變量和它們的值使用此語法:Collapse Copy Code std:string str=Hello,world??;性病:字符串str=你好,世界?。籇EBUG_VALUE_OF(str);DEBUG_VALUE_OF基因(str);And the output would be(provided support for RTTI was not enabled):和輸出將是:(
26、提供的RTTI支持不啟用):Collapse Copy Code name=Hello,world!名稱=你好,世界!The DEBUG_LOG_ENABLE_TYPE_OUTPUT define is to enable/disable outputting of run time type information,this is useful when debuggin applications that dynamically instanciate different objects inheriting from abase class,as it allows the logger
27、 not to output just the variable,but also the type of it.該DEBUG_LOG_ENABLE_TYPE_OUTPUT定義是啟用/禁用輸出的運行時類型信息,這是非常有用的應用程序時debuggin動態(tài)實例化基類繼承從一個不同的對象,因為它允許變量記錄器不只是輸出,而且它的類型的。In most cases this is not important and the complex types of C+makes this abit messy(always printing the full type information for as
28、imple string is really annoying).Because of this,this simple debug log comes with different macros for debugging variables so that that technique can be used only when necessary.在大多數(shù)情況下,這并不重要和C+的復雜類型的使這有點亂(總是打印一個簡單的字符串完整的類型信息,真的很煩)這一點。因此,這個簡單的調(diào)試日志來與變量等不同的宏調(diào)試這一技術(shù)可以在必要時才使用。Collections收藏By relying on t
29、he duck-typing of C+templates,the values in some collections can be also be debugged.通過模板依靠鴨+打字的C+,在某些集合的值也可以進行調(diào)試。In my implementation this relies on the collection at hand having things such as size_type and size()defined on them.我在執(zhí)行這依賴于收集,如手頭有事情size_type和size()他們定義。There are also macros provided
30、to not output all elements in the collection in case the collection is big,the programmer can sayI only want to see the top or bottom 8for example.還有宏提供不輸出的情況下收集的所有元素的集合是大,編程可以說我只希望看到的頂部或底部8為例。The macros for the collection value logging looks like this:收集記錄看起來像這樣價值的宏:Collapse Copy Code#define DEBUG_
31、VALUE_OF_COLLECTION(variable)_debugLog.value_of_collection(#variable,variable,0,all,false);#定義DEBUG_VALUE_OF_COLLECTION(變量)(_debugLog.value_of_collection(#變,變,0,所有的,虛假);)#define DEBUG_VALUE_OF_TOP_COLLECTION(variable,maxCount)_debugLog.value_of_collection(#variable,variable,maxCount,top,false);#定義DE
32、BUG_VALUE_OF_TOP_COLLECTION(變量,maxCount)(_debugLog.value_of_collection(#變,變,maxCount,頂,假);)#define DEBUG_VALUE_OF_BOTTOM_COLLECTION(variable,maxCount)_debugLog.value_of_collection(#variable,variable,maxCount,bottom,false);#定義DEBUG_VALUE_OF_BOTTOM_COLLECTION(變量,maxCount)(_debugLog.value_of_collection
33、(#變,變,maxCount,底部,假);)#define DEBUG_VALUE_AND_TYPE_OF_COLLECTION(variable)_debugLog.value_of_collection(#variable,variable,0,all,true);#定義DEBUG_VALUE_AND_TYPE_OF_COLLECTION(變量)(_debugLog.value_of_collection(#變,變,0,所有,真實);)#define DEBUG_VALUE_AND_TYPE_OF_TOP_COLLECTION(variable,maxCount)_debugLog.val
34、ue_of_collection(#variable,variable,maxCount,top,true);#定義DEBUG_VALUE_AND_TYPE_OF_TOP_COLLECTION(變量,maxCount)(_debugLog.value_of_collection(#變,變,maxCount,頂部真);)#define DEBUG_VALUE_AND_TYPE_OF_BOTTOM_COLLECTION(variable,maxCount)_debugLog.value_of_collection(#variable,variable,maxCount,bottom,true);#
35、定義DEBUG_VALUE_AND_TYPE_OF_BOTTOM_COLLECTION(變量,maxCount)(_debugLog.value_of_collection(#變,變,maxCount,底部,真);)In these macros,the all,top and bottom identifiers are part of an enum used internally by the log class to determine which part of the collection to log.在這些宏,all,top和bottom標識是由內(nèi)部的部分使用了一個枚舉log類
36、,以確定哪些部分收集到的日志。Again,template programming has to be used not only for the duck typing but like in the case of normal variables we need to deduce the argument type at compile time.Because of this the log collection value method looks like this:同樣,模板要使用的編程不僅對鴨打字,但變數(shù)像正常的案件,我們需要的參數(shù)類型推斷在編譯時間。由于這種方法的日志收藏價
37、值,這看起來像:Collapse Copy Code template class Tvoid log:value_of_collection(模板類T無效日志:value_of_collection(const std:string&name,常量標準:字符串和名稱,const T&collection,常量?和收集,const typename T:size_type max,常量的TypeName電話:size_type最大,const list_segment segment,常量list_segment段,const bool outputTypeInformation)布爾常量ou
38、tputTypeInformation)(const T:size_type limit=max!=0?常量電話:size_type限額=最大!=0?std:min T:size_type(max,collection.size():collection.size();標準:分鐘電話:size_type(最大值,collection.size():collection.size()T:size_type startIndex=0;電話:size_type從startIndex=0;switch(segment)交換機(部分)(case all:案件的所有:case top:案件的頂部:star
39、tIndex=0;從startIndex=零;break;打破;case bottom:案底:startIndex=collection.size()-limit;從startIndex=collection.size()-限制;break;打破;)const T:size_type endIndex=startIndex+limit;常量電話:size_type endIndex的=從startIndex+限額;write_indentation();write_indentation();*streamcollection(name;*流集合(名稱;#ifdef DEBUG_LOG_ENA
40、BLE_TYPE_OUTPUT#ifdef DEBUG_LOG_ENABLE_TYPE_OUTPUT if(outputTypeInformation)如果(outputTypeInformation)(*stream(typeid(collection).name();*流(typeid(集合)。名稱();)#endif#endif*stream,collection.size()items)std:endl;*流collection.size()項目)性?。憾鞯拢粀rite_indentation();write_indentation();*streamstd:endl;*流(性?。憾鞯?/p>
41、;if(startIndex!=0)如果(從startIndex!=0)(write_indentation();write_indentation();*stream.std:endl;*流.性病:恩德;)for(T:size_type i=startIndex;i endIndex;+i)的(T:size_type我=從startIndex;我endIndex的;+我)(write_indentation();write_indentation();*streami=collectionistd:endl;*流我=集合一性?。憾鞯拢?if(endIndex!=collection.size
42、()如果(endIndex的!=collection.size()(write_indentation();write_indentation();*stream.std:endl;*流.性?。憾鞯?;)write_indentation();write_indentation();*streamstd:endl;*流)性?。憾鞯拢籹tream-flush();流刷新();)Enabling it all使這一切So that it is possible to disable all logging,without rewriting anything,all logging is hande
43、led by macros,there are three that turn on/off features of this logger:因此,它可以禁用所有記錄,沒有改寫任何事情,所有記錄是由宏handeled,有三個開啟/關(guān)閉功能,此記錄器:DEBUG_LOG_ENABLE DEBUG_LOG_ENABLE_TIMING DEBUG_LOG_ENABLE_TYPE_OUTPUT The first one is the master-switch for the entire thing,the other to enables the timing of methods and the outputting of type information,repectively.第一個是主人,整個事情開關(guān),其他的方法,以使時間和類型的信息輸出,次。To configure these at project level in Visul Studio,right-click the project and click Properties,Configuration Properties,C/C+,Preprocessor and Preprocessor directives and
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 國有土地開發(fā)建設合同范文
- 國際商標使用權(quán)轉(zhuǎn)讓合同標準格式
- 合資成立分公司合同書
- 成都市房屋租賃簡易合同模板
- 項目出資合同模板
- 水產(chǎn)養(yǎng)殖基地建設承包合同范本
- 建筑工程施工合同樣本(律師審核版)
- 訴訟離婚合同范本
- 廣播電視設備智能生物藥品臨床應用技術(shù)考核試卷
- 信息技術(shù)創(chuàng)新與數(shù)字化轉(zhuǎn)型考核試卷
- 2024年單招計算機試題題庫及答案
- 肝癌科普講座課件
- 中國航天“大總師-孫家棟”
- 機電運輸安全基本知識
- 基于51單片機的無功補償裝置
- 幼兒園公開課:大班語言《相反國》課件(優(yōu)化版)
- 水利設施維護投標方案(技術(shù)標)
- 2024屆湖南省長沙市湖南師大附中等校高三上學期月考(二)語文試題(解析版)
- 上??萍及嫘W二年級下冊綜合實踐活動全冊教案
- 氣缸磨損的測量說課教案
- 《高鐵乘務安全管理及應急處置》課程教案-崔藝琳編寫
評論
0/150
提交評論