neku
Codeur roumain
Voila, je partage cette petit classe que j'ai commencé qui permet une petit gestion des exception avec try/throw/catch en c++
le resultat lors de l'exécution :
Certe elle peut être améliorée & optimisée mais c'est une classe faite en vitesse car j'en avais besoin.
Code:
#include <iostream>
#include <fstream>
#include <stdarg.h>
using namespace std;
#ifdef _WIN32_
__declspec (naked) void* __builtin_return_address (int iLevel)
{
__asm
{
push ebx;
mov eax, ebp;
mov ebx, DWORD PTR [esp + 8]; // iLevel
__Next:
test ebx, ebx;
je __break;
dec ebx;
mov eax, DWORD PTR [eax];
jmp __Next;
__break:
mov eax, DWORD PTR [eax + 4];
pop ebx;
ret;
}
}
#endif
#define REDIRECT_COUT_TO_LOG() \
ofstream Log_File("./debug.log", ios::app); \
streambuf* Buffer_log = Log_File.rdbuf(); \
streambuf* Buffer_cout = cout.rdbuf(); \
cout.rdbuf(Buffer_log);
#define REDIRECT_COUT_TO_COUT() \
cout.rdbuf(Buffer_cout); \
Log_File.close();
enum ExceptionType {
RETURN_TRUE,
};
class API_ExceptionHandle {
public:
API_ExceptionHandle (const char* Note, const char* File, const char* Function, int Line, void* Return_Address, void* Call_Return_Address, enum ExceptionType Type);
const char* GetMessage ();
int GetLine ();
const char* GetFile ();
const char* GetFunction ();
void GetArgs (const char* Format, ...);
void* GetReturnAddress ();
void* GetCallReturnAddress ();
private:
string Message;
int Line;
string File;
string Function;
int Type;
void* Return_Address;
void* Call_Return_Address;
};
#define HandleException(Note, Type) API_ExceptionHandle(Note, __FILE__, __PRETTY_FUNCTION__, __LINE__, __builtin_return_address(0), __builtin_return_address(1), Type);
API_ExceptionHandle::API_ExceptionHandle (const char* Note, const char* File, const char* Function, int Line, void* Return_Address, void* Call_Return_Address, enum ExceptionType Type) {
this->Message = Note;
this->Line = Line;
this->Function = Function;
this->File = File;
this->Type = Type;
this->Return_Address = Return_Address;
this->Call_Return_Address = Call_Return_Address;
}
const char* API_ExceptionHandle::GetMessage() {
return this->Message.c_str();
}
const char* API_ExceptionHandle::GetFile() {
return this->File.c_str();
}
const char* API_ExceptionHandle::GetFunction() {
return this->Function.c_str();
}
int API_ExceptionHandle::GetLine() {
return this->Line;
}
void* API_ExceptionHandle::GetReturnAddress() {
return this->Return_Address;
}
void* API_ExceptionHandle::GetCallReturnAddress() {
return this->Call_Return_Address;
}
void API_ExceptionHandle::GetArgs (const char* Format, ...) {
char* tmp = (char*)Format;
bool Begin_Type = false;
bool End_Type = false;
bool Table = false;
int Counter = 0;
int Table_Counter = 0;
va_list va_alist;
va_start(va_alist, Format);
cout << "<Args>" << endl;
while (*tmp) {
if (*tmp == '%') {
Begin_Type = true;
}
if ((*(tmp + 1) == '[') && (*(tmp + 2) == ']') && (Begin_Type == true)) {
Table = true;
if ((*(tmp + 3) == ',') || (*(tmp + 3) == '\0')) {
End_Type = true;
}
}
else {
if ((*(tmp + 1) == ',') || (*(tmp + 1) == '\0')) {
End_Type = true;
}
}
if ((Begin_Type == true) && (End_Type == true)) {
Counter++;
cout << " |-- Arg [" << Counter << "]: ";
if (*tmp == 'i' || *tmp == 'd')
cout << dec << va_arg(va_alist, int) << endl;
else if (*tmp == 'f') {
cout << dec << va_arg(va_alist, double) << endl;
}
else if (*tmp == 'x') {
cout << "0x" << hex << va_arg(va_alist, int) << endl;
}
else if (*tmp == 's') {
if (Table) {
char** tmpTab = va_arg(va_alist, char**);
char* tmpString = *(tmpTab + 0);
cout << endl;
while (tmpString) {
cout << " | |----- [" << dec << Table_Counter << "]: " << tmpString << endl;
tmpString = *(++tmpTab);
Table_Counter++;
}
cout << " |" << endl;
Table_Counter = 0;
}
else {
char* tmpString = va_arg(va_alist, char*);
cout << tmpString << endl;
}
}
if (Table)
tmp += 2;
Begin_Type = false;
End_Type = false;
Table = false;
}
*tmp++;
}
va_end(va_alist);
cout << "</Args>" << endl;
}
int main (int argc, char const* argv[])
{
//REDIRECT_COUT_TO_LOG()
try {
if (true) throw HandleException("Oh non ca a encore ... ! :'(", RETURN_TRUE)
cout << "coucou" << endl;
}
catch (API_ExceptionHandle &eHandle) {
cout << "<File>" << endl << " " << eHandle.GetFile() << endl << "</File>" << endl;
cout << "<Function>" << endl << " " << eHandle.GetFunction() << endl << "</Function>" << endl;
cout << "<Line>" << endl << " " << eHandle.GetLine() << endl << "</Line>" << endl;
cout << "<Return Address>" << endl << " " << eHandle.GetReturnAddress() << endl << "</Return Address>" << endl;
cout << "<Call Return Address>" << endl << " " << eHandle.GetReturnAddress() << endl << "</Call Return Address>" << endl;
cout << "<Note>" << endl << " " << eHandle.GetMessage() << endl << "</Note>" << endl;
eHandle.GetArgs("%i,%s[]", argc, argv);
}
//REDIRECT_COUT_TO_COUT()
return 0;
}
Code:
ordinateur-de-leandre-gohy:~/Desktop/DVRNS leandregohy$ ./test
<File>
test.cpp
</File>
<Function>
int main(int, const char**)
</Function>
<Line>
181
</Line>
<Return Address>
0x1d6e
</Return Address>
<Call Return Address>
0x1d6e
</Call Return Address>
<Note>
Oh non ca a encore ... ! :'(
</Note>
<Args>
|-- Arg [1]: 1
|-- Arg [2]:
| |----- [0]: ./test
|
</Args>
ordinateur-de-leandre-gohy:~/Desktop/DVRNS leandregohy$