any way to detect, catch or provent crash from an invalid pointer?
-
I did following 2 tests:
char*psz=0;
//then call
sprintf(psz,"%d",10);class MyClass
{
public:
CString GetName()
{
return "Hello";
}
};//then call
MyClass*p=(MyClass*)10000;
//display
p->GetName();in first test, app crashed and no idea to try-catch it. in second test, GetName() is called properly without any problem (funny). My Q is: how to detect, catch or provent crash from invalid pointers as tests above, or other common cases? .
In case 1 you injected a memory address fault which is not, as far as I am aware, a catchable exception. In case 2 you have created an object pointer of your class, which allows you to call any methods of the class. You will only get a failure if you attempt to access any instance variables of the object. However, again this would be a memory address fault, which is not catchable.
The best things in life are not things.
-
I did following 2 tests:
char*psz=0;
//then call
sprintf(psz,"%d",10);class MyClass
{
public:
CString GetName()
{
return "Hello";
}
};//then call
MyClass*p=(MyClass*)10000;
//display
p->GetName();in first test, app crashed and no idea to try-catch it. in second test, GetName() is called properly without any problem (funny). My Q is: how to detect, catch or provent crash from invalid pointers as tests above, or other common cases? .
the first few memory pages (starting at adr zero) are never mapped into a process, therefore accessing them (such as when dereferencing a null pointer) will be trapped by Windows. Address 10000 seems to be beyond those special pages, and is likely to exist within your app, therefore you may well be able to read there, while it is not recommended writing there! :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
the first few memory pages (starting at adr zero) are never mapped into a process, therefore accessing them (such as when dereferencing a null pointer) will be trapped by Windows. Address 10000 seems to be beyond those special pages, and is likely to exist within your app, therefore you may well be able to read there, while it is not recommended writing there! :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
I did following 2 tests:
char*psz=0;
//then call
sprintf(psz,"%d",10);class MyClass
{
public:
CString GetName()
{
return "Hello";
}
};//then call
MyClass*p=(MyClass*)10000;
//display
p->GetName();in first test, app crashed and no idea to try-catch it. in second test, GetName() is called properly without any problem (funny). My Q is: how to detect, catch or provent crash from invalid pointers as tests above, or other common cases? .
includeh10 wrote:
in first test, app crashed and no idea to try-catch it.
You tried to write to an address which was not allocated as writable memory to your application. The operating system detects that and issues a system exception for the application.
includeh10 wrote:
in second test, GetName() is called properly without any problem (funny).
You are calling a method via static binding. Static binding in the code of your application is normal for your application. The method itself is in the code space. Thus legal as well. The method doesn't address any illegal addresses so no problem. > how to detect, catch or provent crash from invalid pointers as tests above, or other common cases? Find or buy libraries which detect memory problems, of many types. Build your application with those. Then run your application testing ALL of the code paths (there are other tools that track that.) The library will tell you about improper memory usage.
-
Luc Pattyn wrote:
Address 10000
gives an access violation. I think it is still well outside of 'user' address spaces.
The best things in life are not things.
IIRC adr 0x1000 (and hence also 10000) can be inside or outside of the regular process map, most of the map can be user selected through linker directives or switches. However the first few pages are always set aside as a protective measure. :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
includeh10 wrote:
how to detect, catch or provent crash from invalid pointers as tests above, or other common cases?
This might work:
MyClass *p = (MyClass *) 10000;
if (! IsBadReadPtr(p, sizeof(MyClass))
p->GetName();But I've heard it can be unreliable, too. See here for more discussion.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
Both BadReadPtr() and BadWritePtr() can detect it is an invalid pointer, thanks.
-
the first few memory pages (starting at adr zero) are never mapped into a process, therefore accessing them (such as when dereferencing a null pointer) will be trapped by Windows. Address 10000 seems to be beyond those special pages, and is likely to exist within your app, therefore you may well be able to read there, while it is not recommended writing there! :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
You're are wrong (even if you're always right!), jschell answer below is correct. The code
p->GetName();
simply works because there's no usage of the implicit passed
this
pointer inside. Try, for instance:#include <iostream>
using namespace std;
class A
{
int a;
public:
void play(){cout << "Hi Luc!" << endl;}
void game_over(){cout << a << endl;}
};int main()
{
A * pa = 0;
pa->play();
pa->game_over();
return 0;
}If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
You're are wrong (even if you're always right!), jschell answer below is correct. The code
p->GetName();
simply works because there's no usage of the implicit passed
this
pointer inside. Try, for instance:#include <iostream>
using namespace std;
class A
{
int a;
public:
void play(){cout << "Hi Luc!" << endl;}
void game_over(){cout << a << endl;}
};int main()
{
A * pa = 0;
pa->play();
pa->game_over();
return 0;
}If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles]sometimes you are right too, and this seems to be one of them. :thumbsup:
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
Both BadReadPtr() and BadWritePtr() can detect it is an invalid pointer, thanks.
those functions are not foolproof: IsBadXxxPtr should really be called CrashProgramRandomly[^]
-
I did following 2 tests:
char*psz=0;
//then call
sprintf(psz,"%d",10);class MyClass
{
public:
CString GetName()
{
return "Hello";
}
};//then call
MyClass*p=(MyClass*)10000;
//display
p->GetName();in first test, app crashed and no idea to try-catch it. in second test, GetName() is called properly without any problem (funny). My Q is: how to detect, catch or provent crash from invalid pointers as tests above, or other common cases? .
_CrtDumpMemoryLeaks() is provided and works efficiently. check the following link http://msdn.microsoft.com/en-us/library/e5ewb1h3(v=VS.80).aspx[^] -- CHEERS!!!