shyamal said:
I want to display memory content using C++ on LINUX. For example, the
user may ask to display 256 bytes from 0x1000ff00. The problem is , if
any location is invalid, the program will coredump because of attempt
to access invalid memory.I understand that in Windows OS there is a
function that tells if a memory location is valid or invalid. Is there
a similar function in Linux? How does gdb display memory content?
I will appreciate a response.
This is off topic here - try comp.unix.programmer.
Hint - any system calls you sent an invalid address to do not abort,
they will return an error code. Try "write()-ing" the memory range to a
pipe and read it back. Or simply catch the SIGSEGV signal and throw an
exception when the signal handler is caught - however you will need to
make sure you use -fnon-call-exceptions in when compiling your code.
Here is an example using signals.
#include <iostream>
#include <signal.h>
void SegFaultAction( int , siginfo_t *, void * );
void SetupSignal()
{
struct sigaction a_sig[1] = { { 0 } };
struct sigaction a_old_sig[1] = { { 0 } };
a_sig->sa_sigaction = SegFaultAction;
a_sig->sa_flags = SA_SIGINFO | SA_NOMASK;
if ( -1 == sigaction( SIGSEGV, a_sig, a_old_sig ) )
{
throw "Failed to set handler";
}
}
void SegFaultAction( int i_num, siginfo_t * i_info, void * i_val )
{
const siginfo_t & v = * i_info;
std::cout << v.si_signo << "= Signal number\n";
std::cout << v.si_errno << "= An errno value\n";
std::cout << v.si_code << "= Signal code\n";
std::cout << v.si_pid << "= Sending process ID\n";
std::cout << v.si_uid << "= Real user ID of sending process\n";
std::cout << v.si_status << "= Exit value or signal\n";
std::cout << v.si_utime << "= User time consumed\n";
std::cout << v.si_stime << "= System time consumed\n";
// std::cout << (int) v.si_value << "= Signal value\n";
std::cout << v.si_int << "= POSIX.1b signal\n";
std::cout << v.si_ptr << "= POSIX.1b signal\n";
std::cout << v.si_addr << "= Memory location which caused fault\n";
std::cout << v.si_band << "= Band event\n";
std::cout << v.si_fd << "= File descriptor\n";
// throw "HELP";
throw * i_info;
}
char * foo = (char*) 0xdeadbeef;
int main()
{
SetupSignal();
try
{
* foo = 1;
}
catch ( const siginfo_t & v )
{
// caught a signal
std::cout << v.si_signo << "= Signal number\n";
std::cout << v.si_errno << "= An errno value\n";
std::cout << v.si_code << "= Signal code\n";
std::cout << v.si_pid << "= Sending process ID\n";
std::cout << v.si_uid << "= Real user ID of sending process\n";
std::cout << v.si_status << "= Exit value or signal\n";
std::cout << v.si_utime << "= User time consumed\n";
std::cout << v.si_stime << "= System time consumed\n";
// std::cout << (int) v.si_value << "= Signal value\n";
std::cout << v.si_int << "= POSIX.1b signal\n";
std::cout << v.si_ptr << "= POSIX.1b signal\n";
std::cout << v.si_addr << "= Memory location which caused fault\n";
std::cout << v.si_band << "= Band event\n";
std::cout << v.si_fd << "= File descriptor\n";
}
catch ( ... )
{
std::cout << "caught somthing else\n";
}
}