Unix Programming - Validate a pointer

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > December 2004 > Validate a pointer





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Validate a pointer
Bryan Bullard

2004-12-10, 5:55 pm

Hi, what the most UNIX standard way of validating that an address can be
read or written to?


Måns Rullgård

2004-12-10, 5:55 pm

"Bryan Bullard" <replay@to.group.com> writes:

> Hi, what the most UNIX standard way of validating that an address can be
> read or written to?


Writing your program in such a way that you know what your pointers
are pointing to in the first place. Anything else is bound to break
in some situation.

--
Måns Rullgård
mru@inprovide.com
Chuck Dillon

2004-12-10, 5:55 pm

Bryan Bullard wrote:
> Hi, what the most UNIX standard way of validating that an address can be
> read or written to?
>
>


It depends on what you mean by "valid", "read" and "write".

Use google to search this group for the terms "valid" and "address" and
you will find a couple recent threads on the subject.

-- ced

--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.
Bryan Bullard

2004-12-10, 5:55 pm


"Chuck Dillon" <spam@nimblegen.com> wrote in message
news:cpctop$96i$1@grandcanyon.binc.net...
> Bryan Bullard wrote:
>
> It depends on what you mean by "valid", "read" and "write".
>
> Use google to search this group for the terms "valid" and "address" and
> you will find a couple recent threads on the subject.


I mean an address that won't cause a protection type fault if I read to or
write to it.


Bryan Bullard

2004-12-10, 5:55 pm


"Måns Rullgård" <mru@inprovide.com> wrote in message
news:yw1xis7a3uqy.fsf@ford.inprovide.com...
> "Bryan Bullard" <replay@to.group.com> writes:
>
>
> Writing your program in such a way that you know what your pointers
> are pointing to in the first place. Anything else is bound to break
> in some situation.


This is for a library that needs to test the range of a pointer that the
caller passes.


Erik Max Francis

2004-12-10, 5:55 pm

Bryan Bullard wrote:

> I mean an address that won't cause a protection type fault if I read to or
> write to it.


There is no completely safe and reliable way to do it. Besides, this
wouldn't really solve the problem; there are certainly dangling and
invalid pointers which could be passed which wouldn't cause a protection
fault.

--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
Defeat is a school in which truth always grows strong.
-- Henry Ward Beecher
Bryan Bullard

2004-12-10, 5:55 pm


"Erik Max Francis" <max@alcyone.com> wrote in message
news:gcidnQ1IIIxIlCfcRVn-gw@speakeasy.net...
> Bryan Bullard wrote:
>
or[vbcol=seagreen]
>
> There is no completely safe and reliable way to do it.


Of course there is. A UNIX kernel does it on every page fault.

The Win32 equivelent would be IsBadReadPtr() and IsBadWritePtr()

Isn't there a common way to find out the size of the data segment at the
very least?

> Besides, this
> wouldn't really solve the problem; there are certainly dangling and
> invalid pointers which could be passed which wouldn't cause a protection
> fault.


Wrong. "dangling and invalid pointers which could be passed which wouldn't
cause a protection fault", as you say, are not a problem in this particual
situation.


Måns Rullgård

2004-12-10, 5:55 pm

"Bryan Bullard" <replay@to.group.com> writes:

> "Erik Max Francis" <max@alcyone.com> wrote in message
> news:gcidnQ1IIIxIlCfcRVn-gw@speakeasy.net...
>
> Of course there is. A UNIX kernel does it on every page fault.


The only reliable way to find out whether access is allowed is to
attempt the access.

> The Win32 equivelent would be IsBadReadPtr() and IsBadWritePtr()


It's no news that win32 encourages bad programming style.

> Isn't there a common way to find out the size of the data segment at the
> very least?


Yes, but the mapped pages of a process need not be contiguous, so
knowing the total size is of little help.

>
> Wrong. "dangling and invalid pointers which could be passed which wouldn't
> cause a protection fault", as you say, are not a problem in this particual
> situation.


In that case you must be doing something unusual. If you tell us more
about what you are trying to achieve, maybe someone can suggest a good
way to do it.

--
Måns Rullgård
mru@inprovide.com
Rich Teer

2004-12-10, 5:55 pm

On Fri, 10 Dec 2004, Bryan Bullard wrote:

> Of course there is. A UNIX kernel does it on every page fault.


But the kernel doesn't check the value of a pointer. The page fault
happens as a result of the pointer being dereferenced.

--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
Bryan Bullard

2004-12-10, 5:55 pm


"Rich Teer" <rich.teer@rite-group.com> wrote in message
news:Pine.SOL.4.58.0412101418560.2755@zaphod...
> On Fri, 10 Dec 2004, Bryan Bullard wrote:
>
>
> But the kernel doesn't check the value of a pointer. The page fault
> happens as a result of the pointer being dereferenced.


When a page fault happens the kernel memory manager checks the value of the
address *attempted* by the user process. The kernel then determines what
action to take (e.g., swap-in memory from disk if the address is valid then
restart the instruction that cause the page fault or dump core if the
address is not valid). If you wrote a book on Solaris system programming
you should know this.


Rich Teer

2004-12-10, 5:55 pm

On Fri, 10 Dec 2004, Bryan Bullard wrote:

> When a page fault happens the kernel memory manager checks the value of the
> address *attempted* by the user process. The kernel then determines what
> action to take (e.g., swap-in memory from disk if the address is valid then
> restart the instruction that cause the page fault or dump core if the


Yes, but that happens AFTER an attempt is made to dereference the
pointer. In other words, what the kernel does when a bad page trap
happens is analogous to a user land application installing a SEGV
or BUS signal handler.

The kernel dereferences the pointer without checking its value.
The MMU handles the virtual to physical address translation, and
IT, not the kernel, will flag the invalid reference to the kernel.

Do you really think that every pointer reference in the kernel
looks like this:

if (pointer_is_valid (ptr))
dereference_pointer (ptr);
else
send_proc_sigsegv ();

That's incredably inefficient!

> address is not valid). If you wrote a book on Solaris system programming
> you should know this.


Indeed, and I'm trying to explain it to you...

--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
Bryan Bullard

2004-12-10, 5:55 pm


"Rich Teer" <rich.teer@rite-group.com> wrote in message
news:Pine.SOL.4.58.0412101508410.3239@zaphod...
> On Fri, 10 Dec 2004, Bryan Bullard wrote:
>
the[vbcol=seagreen]
what[vbcol=seagreen]
then[vbcol=seagreen]
>
> Yes, but that happens AFTER an attempt is made to dereference the
> pointer. In other words, what the kernel does when a bad page trap
> happens is analogous to a user land application installing a SEGV
> or BUS signal handler.
>
> The kernel dereferences the pointer without checking its value.
> The MMU handles the virtual to physical address translation, and
> IT, not the kernel, will flag the invalid reference to the kernel.


Okay, obviously the system does not trap into the kernel until *after* the
page fault was detected by the MMU. I left this part out. I assumed this
was obvious. There was a communication problem.

> Do you really think that every pointer reference in the kernel
> looks like this:
>
> if (pointer_is_valid (ptr))
> dereference_pointer (ptr);
> else
> send_proc_sigsegv ();
>
> That's incredably inefficient!


I didn't say every pointer (memory) reference. I said on every page fault.
And yes, on every page fault something *like* that happens. Which is my
point. If the kernel can look through the page tables for a address in a
process to determine what type action to take, can a process too?

programming[vbcol=seagreen]
>
> Indeed, and I'm trying to explain it to you...


Not likely. ;)

> --
> Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"
>
> President,
> Rite Online Inc.
>
> Voice: +1 (250) 979-1638
> URL: http://www.rite-group.com/rich



Måns Rullgård

2004-12-10, 5:55 pm

"Bryan Bullard" <replay@to.group.com> writes:

> I didn't say every pointer (memory) reference. I said on every page fault.
> And yes, on every page fault something *like* that happens. Which is my
> point. If the kernel can look through the page tables for a address in a
> process to determine what type action to take, can a process too?


Userland has no way of looking at the page tables, and a properly
designed program has no reason to do so.

>
> Not likely. ;)


Not likely to succeed, you mean.

--
Måns Rullgård
mru@inprovide.com
Erik Max Francis

2004-12-10, 8:47 pm

Bryan Bullard wrote:

> I didn't say every pointer (memory) reference. I said on every page fault.
> And yes, on every page fault something *like* that happens. Which is my
> point. If the kernel can look through the page tables for a address in a
> process to determine what type action to take, can a process too?


No.

I mean, look what's happening here: You're asking how to do something.
You're being told it's not possible, but you're insisting that you
know better than the people telling you it's not possible and that it
really _is_ possible. But how do you know this without already knowing
the answer to your question? Either you know and have your answer, or
you don't know and can't be sure the answer isn't "no."

So since you "know" there's a solution, you'll have no problem producing
it, right?

--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
If love is the answer, could you rephrase the question?
-- Lily Tomlin
Michael B Allen

2004-12-10, 8:47 pm

On Fri, 10 Dec 2004 14:57:43 -0500, Bryan Bullard wrote:

> I mean an address that won't cause a protection type fault if I read to
> or write to it.


Try it. If the program segfaults it wasn't a valid address :->

Mike
Ognen Duzlevski

2004-12-16, 7:44 pm

Erik Max Francis <max@alcyone.com> wrote:
> I mean, look what's happening here: You're asking how to do something.
> You're being told it's not possible, but you're insisting that you
> know better than the people telling you it's not possible and that it
> really _is_ possible. But how do you know this without already knowing
> the answer to your question? Either you know and have your answer, or
> you don't know and can't be sure the answer isn't "no."


I suspect Bryan is going to hit a recursive point here and tell you again about IsBadReadPtr() and IsBadWritePtr() in
Win32. This apparently means it is possible. Then someone will educate him on Win32 and soon you will be posing the
question above to which....oh, no, wait...

Ognen
Rich Teer

2004-12-16, 7:44 pm

On Fri, 10 Dec 2004, Bryan Bullard wrote:

> Okay, obviously the system does not trap into the kernel until *after* the
> page fault was detected by the MMU. I left this part out. I assumed this
> was obvious. There was a communication problem.


It's only obvious if one knows it. ;-)

> I didn't say every pointer (memory) reference. I said on every page fault.
> And yes, on every page fault something *like* that happens. Which is my


Actually, I don't think it does. When an attempt to access an unmapped
page occurs, the kernel trap handler loads that page, sets up the
mapping tables, and re-runs the instruction that caused the trap. It
does no checking like the psuedocode I showed.

> point. If the kernel can look through the page tables for a address in a
> process to determine what type action to take, can a process too?


No; the page tables are data structures private to the kernel.

As someone else suggested, if you want to know if a pointer is
valid or not, arrange to trap the apprpriate signals, and handle
them as you see fit.

You can't detect before hand whether a pointer is "valid" prior
to using it (NULL pointers are the exception to this rule). The
best you can do is try to recover in a meaningful way in the signal
handler for the apprpriate signal. Mind you, the defaukt action of
dumping core and aborting the program is probably the most sensible
behaviour.

>
> Not likely. ;)


Hey, you're the one asking the questions...

--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
Rich Teer

2004-12-16, 7:44 pm

On Fri, 10 Dec 2004, Michael B Allen wrote:

> Try it. If the program segfaults it wasn't a valid address :->


Indeed. There's a lot to be said for using Occam's razor! :-)

--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
Jason Spence

2004-12-16, 7:44 pm

See the IRIX end(3C) man page, which has a good explanation of how it
works on IRIX. Much of it applies to any ELF-based system, regardless
of processor. FreeBSD also has a end(3) manpage, which is more
succinct.

Basically, the dynamic loader provides symbols indicating the start and
end of your data segment at load time. Since these change with calls
to malloc(), you should call sbrk(0) to get the current end. But
beware of the things like DSOs mentioned in the IRIX man page! In that
case, you will probably have to read your own ELF header. If you're
calling dlopen, though, then you'll just have to be clever, because
there isn't a simple way to get the information you're after; you'll
have to keep track of it yourself for each dlopen().

x86 also has a lsl instruction to interrogate the segmentation data
structures directly, but that doesn't always work because of the way
some systems set up the descriptor table.

You can try it, though:
http://lightconsulting.com/~thalakan/dump_selectors.c

Brian Raiter

2004-12-16, 7:44 pm

> Userland has no way of looking at the page tables, and a properly
> designed program has no reason to do so.


Well, one might argue that if the program in question is a debugging
tool.

I do agree in principle with what you're saying, as well as the other
people in this thread that are generally discouraging the idea. That
said, however, it should be admitted that there is a way to do what
the original poster asked for, sort of. It's a hack, and I have no
idea how portable it is. Again, it should only be used as a debugging
tool, and not even as a first line of defense against coding errors.

The hack leverages the fact in most modern Unices, the kernel does
have the ability to validate pointers coming from userland, and that
system calls will do just that, to avoid dealing with segfaults in the
kernel. So by passing a pointer to a system call, you can get it
validated as a side effect. So you just use a system call that has no
other side effects. For example:

#define valid_ptr(p) ((access(p) == -1) ? (errno != EFAULT) : 1)

Note that you can still get a false return value on a valid pointer if
there isn't a NUL byte present to terminate the "string" at p. Again,
access(2) is being used simply because it has no side effects.
Something like open(2) would have worked just as well, except that
you'd have to check to see if a valid file handle was returned and
close it if so.

By the way: The Windows functions IsBadReadPtr() and IsBadWritePtr()
work, if memory serves, via the x86 lsl instruction. This works
because Windows largely uses segments to manage memory. The lsl
instruction isn't really useful under Linux because Linux relies on
paging to manage memory instead. A running Linux system only defines
four segments, which are shared by all running processes (a code and
data segment for kernel-space, and a code and data segment for
userland), and just swaps pages of memory in and out of those segments
as needed. So testing the segment limits under Linux tells you
nothing. I don't know about other x86-based Unices, but I wouldn't be
surprised if most of them worked similarly.

b
Måns Rullgård

2004-12-16, 7:44 pm

Rich Teer <rich.teer@rite-group.com> writes:

> As someone else suggested, if you want to know if a pointer is
> valid or not, arrange to trap the apprpriate signals, and handle
> them as you see fit.


Don't do that. The signal may only be triggered after God knows what
damage has been done. Any (all) your data may have been trashed
before you hit an unmapped address.

> You can't detect before hand whether a pointer is "valid" prior
> to using it (NULL pointers are the exception to this rule). The


Not even NULL pointers are an exception. I have mapped page zero a
few times to ease some debugging.

--
Måns Rullgård
mru@inprovide.com
Bjorn Reese

2004-12-16, 7:44 pm

On Fri, 10 Dec 2004 19:57:43 +0000, Bryan Bullard wrote:

> I mean an address that won't cause a protection type fault if I read to or
> write to it.


Some platforms have the mincore() system call, which may be the
closest to what you are looking for.

--
mail1dotstofanetdotdk

Måns Rullgård

2004-12-16, 7:44 pm

"Bjorn Reese" <breese@see.signature> writes:

> On Fri, 10 Dec 2004 19:57:43 +0000, Bryan Bullard wrote:
>
>
> Some platforms have the mincore() system call, which may be the
> closest to what you are looking for.


mincore(2) is useless for this purpose. It will tell if a page is
actually in physical memory at the time of the call. It will not
distinguish between unmapped and swapped out pages.

--
Måns Rullgård
mru@inprovide.com
Rich Teer

2004-12-16, 7:44 pm

On Sat, 11 Dec 2004, Måns Rullgård wrote:

> Rich Teer <rich.teer@rite-group.com> writes:
>
>
> Don't do that. The signal may only be triggered after God knows what
> damage has been done. Any (all) your data may have been trashed
> before you hit an unmapped address.


I agree that the general rule should be to just let the core dump
and the process terminate. But I guess it's conceivable that one
might want to do more than that in this situation (although as you
say, the validity of any data is any one's guess).

> Not even NULL pointers are an exception. I have mapped page zero a
> few times to ease some debugging.


OK, that's one exception to the rule! But generally speaking,
if a pointer one is abouty to dereference is NULL, it's a bug.

ANnoyingly, HP-UX used to (still does?) map page 0 by default,
so dereferencing a NULL pointer would NOT cause a core dump.
I was once involved with a project to port a large suite of
programs from HP-UX to Solaris, and the amature programmers
has NULL pointer dereferences all over the place. It caused
all sorts of problems... :-(

--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
Måns Rullgård

2004-12-16, 7:44 pm

Rich Teer <rich.teer@rite-group.com> writes:

> On Sat, 11 Dec 2004, Måns Rullgård wrote:
>
>
> I agree that the general rule should be to just let the core dump
> and the process terminate. But I guess it's conceivable that one
> might want to do more than that in this situation (although as you
> say, the validity of any data is any one's guess).


Well, there are cases where it might be meaningful to do something
after a SIGSEGV, but someone who doesn't know how to do that is not
competent enough to be doing the sort of programming where it could be
useful.

>
> OK, that's one exception to the rule! But generally speaking,
> if a pointer one is abouty to dereference is NULL, it's a bug.


Yes, dereferencing NULL is a bug. In my case, I had some function
pointers that erroneously were getting set to NULL, and when they were
used, the core dumps didn't contain a valid stack trace, for some
reason (this was on Alpha machines). Mapping a page of at address 0
caused an illegal instruction trap, and for whatever reason, the stack
traces were good, and I could easily find the bug.

> ANnoyingly, HP-UX used to (still does?) map page 0 by default,
> so dereferencing a NULL pointer would NOT cause a core dump.


I've heard of it.

> I was once involved with a project to port a large suite of
> programs from HP-UX to Solaris, and the amature programmers
> has NULL pointer dereferences all over the place. It caused
> all sorts of problems... :-(


Simply mapping a page of zeros read-only at address 0 should have been
enough to make the program run. Of course, it's still an incredibly
stupid way to write a program.

--
Måns Rullgård
mru@inprovide.com
Ara.T.Howard@noaa.gov

2004-12-16, 7:44 pm

Måns Rullgård

2004-12-16, 7:44 pm

Ara.T.Howard@noaa.gov writes:

> On Sat, 11 Dec 2004, [iso-8859-1] Måns Rullgård wrote:
>
>
> in some cases you might be able to simply fork and then dereference
> the pointer - the memory you trash will be the memory of the child
> unless you are doing something like mmap, etc. this is also quite
> expensive but, in some systems, not as much as it once was: perhaps
> equal to creating a thread. i guess it depends on how important and
> how often one would do this.


My point was that by the time you decide to dereference your possibly
invalid pointer, lots of data might have be trampled on. Likely areas
are your stack, in which case your program will anyway crash when the
current function returns.

There are no shortcuts to writing good code. Start with a good
design, implement it well, and you'll know which pointers are valid
without testing them.

--
Måns Rullgård
mru@inprovide.com
Rich Teer

2004-12-16, 7:44 pm

On Sat, 11 Dec 2004, Måns Rullgård wrote:

> Well, there are cases where it might be meaningful to do something
> after a SIGSEGV, but someone who doesn't know how to do that is not
> competent enough to be doing the sort of programming where it could be
> useful.


Agreed.

> Yes, dereferencing NULL is a bug. In my case, I had some function
> pointers that erroneously were getting set to NULL, and when they were
> used, the core dumps didn't contain a valid stack trace, for some
> reason (this was on Alpha machines). Mapping a page of at address 0
> caused an illegal instruction trap, and for whatever reason, the stack
> traces were good, and I could easily find the bug.


Go figure!

> Simply mapping a page of zeros read-only at address 0 should have been
> enough to make the program run. Of course, it's still an incredibly
> stupid way to write a program.


It did--but we wamted to point out to the customer how bad their
code was. IIRC (it was a few years ago now), there was some
politics going on about how long the port was taking. We had
to show the customer that as well as porting their code from
HP-UX to Solaris (which shouldn't have been THAT hard), we also
had to debug their code too, which added considerably to the
porting time.

There were silly constructs like this:

ptr = getenv ("SOME_UNDOCUMENTED_ENV_VAR");
sprintf (name, "%s/foobar.dat", ptr);
fd = open (name, O_RDONLY);
...

Note the complete lack of error checking. :-(

Great engineers, I'm sure (these guy designed jet engines, for
crying out loud!), but terrible programmers...

--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
Måns Rullgård

2004-12-16, 7:44 pm

Rich Teer <rich.teer@rite-group.com> writes:

>
> It did--but we wamted to point out to the customer how bad their
> code was. IIRC (it was a few years ago now), there was some
> politics going on about how long the port was taking. We had
> to show the customer that as well as porting their code from
> HP-UX to Solaris (which shouldn't have been THAT hard), we also
> had to debug their code too, which added considerably to the
> porting time.
>
> There were silly constructs like this:
>
> ptr = getenv ("SOME_UNDOCUMENTED_ENV_VAR");
> sprintf (name, "%s/foobar.dat", ptr);
> fd = open (name, O_RDONLY);
> ...
>
> Note the complete lack of error checking. :-(


I've seen worse. Some time ago, someone was asking about porting from
some Unix with the silly mapping at 0, and they had lots of cases of
dereferencing NULL pointers as in if(*ptr) where the test should have
been if(ptr). Out of pure luck, a valid pointer apparently never
pointed to a value of zero.

> Great engineers, I'm sure (these guy designed jet engines, for
> crying out loud!), but terrible programmers...


All too common.

--
Måns Rullgård
mru@inprovide.com
Dmitry Karasik

2004-12-16, 7:45 pm

Hi Bryan!

On 10 Dec 04 at 22:40, "Bryan" (Bryan Bullard) wrote:

Bryan> "Erik Max Francis" <max@alcyone.com> wrote in message
Bryan> news:gcidnQ1IIIxIlCfcRVn-gw@speakeasy.net...[vbcol=seagreen]
Bryan> or[vbcol=seagreen]

Bryan> Of course there is. A UNIX kernel does it on every page fault.

Bryan> The Win32 equivelent would be IsBadReadPtr() and IsBadWritePtr()

Windows can afford this on i386 architecture, using VERR and VERW assembler
instructions. I don't know of any UNIX abstraction that goes anywhere close.

--
Sincerely,
Dmitry Karasik

---
catpipe Systems ApS
*BSD solutions, consulting, development
www.catpipe.net
+45 7021 0050
Bryan Bullard

2004-12-16, 7:45 pm

Thanks to everyone that posted.


Bryan Bullard

2004-12-16, 7:45 pm


"Erik Max Francis" <max@alcyone.com> wrote in message
news:Pb-dnS8xRoRq3yfcRVn-vA@speakeasy.net...

> But how do you know this without already knowing
> the answer to your question?


Because having a background in OS internals does not make me a Unix expert.


Bryan Bullard

2004-12-16, 7:45 pm


"Rich Teer" <rich.teer@rite-group.com> wrote in message
news:Pine.SOL.4.58.0412102128420.3239@zaphod...
> On Fri, 10 Dec 2004, Bryan Bullard wrote:
>
fault.[vbcol=seagreen]
>
> Actually, I don't think it does. When an attempt to access an unmapped
> page occurs, the kernel trap handler loads that page, sets up the
> mapping tables, and re-runs the instruction that caused the trap. It
> does no checking like the psuedocode I showed.
>

On systems that page-out memory to some type of device, on each page fault
the kernel would need to know what to do to handle the page fault. The
address value is the only metric to determine the next course of action.
The kernel would need to test the range not only to determine if mapping in
a page would be a legal action but where to load that page from (e.g., from
the swap space, from an executable binary image if a code segment, from a
parent process during a fork, etc ...).


amujoo@yahoo.com

2004-12-16, 7:45 pm

You can see /proc/self/maps and compare the pointer value with the
address ranges given along with the permissions for each region. If the
pointer value seems to be unfit then you can say that the pointer is
invalid.

Måns Rullgård

2004-12-16, 7:45 pm

amujoo@yahoo.com writes:

> You can see /proc/self/maps and compare the pointer value with the
> address ranges given along with the permissions for each region. If the
> pointer value seems to be unfit then you can say that the pointer is
> invalid.


Even if the pointer is within a mapped region, it can be totally wrong
to use it. Never use a pointer that you don't *know* is correct, from
the design of the program. In a library, you'll just have to trust
the user to supply valid data.

--
Måns Rullgård
mru@inprovide.com
Bryan Bullard

2004-12-16, 7:45 pm


<amujoo@yahoo.com> wrote in message
news:1103006094.080644.106090@f14g2000cwb.googlegroups.com...
> You can see /proc/self/maps and compare the pointer value with the
> address ranges given along with the permissions for each region. If the
> pointer value seems to be unfit then you can say that the pointer is
> invalid.
>


Excellent! Thank you.


Måns Rullgård

2004-12-16, 7:45 pm

"Bryan Bullard" <replay@to.group.com> writes:

> <amujoo@yahoo.com> wrote in message
> news:1103006094.080644.106090@f14g2000cwb.googlegroups.com...
>
> Excellent! Thank you.


Noooo. Don't do it. If the pointer is invalid, chances are there is
a bug somewhere that has already trashed enough of you memory that
even calling fopen() might crash. Even if you manage to read enough
to find out the pointer is bad, what will you do about it? It's much
better to just let the program receive a SIGSEGV and dump core.

I have said it before, and I will say it again: unless a pointer is
*known* to be good, there is *no* way to validate it, and, even if
there were, there would be *nothing* you could sensibly do at that
point.

A bug is a bug. It must be thoroughly stomped, poisoned, or otherwise
annihilated. If you just brush it aside, it *will* come back and bite
you later.

--
Måns Rullgård
mru@inprovide.com
Rich Teer

2004-12-16, 7:45 pm

On Tue, 14 Dec 2004, Måns Rullgård wrote:

> I have said it before, and I will say it again: unless a pointer is
> *known* to be good, there is *no* way to validate it, and, even if
> there were, there would be *nothing* you could sensibly do at that
> point.
>
> A bug is a bug. It must be thoroughly stomped, poisoned, or otherwise
> annihilated. If you just brush it aside, it *will* come back and bite
> you later.


Adding to this, /proc/self/maps is not portable, which is another
reason to avoid it (although the reasons Måns' gives are better).

--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
Bjorn Reese

2004-12-16, 7:45 pm

Rich Teer wrote:

> Adding to this, /proc/self/maps is not portable, which is another
> reason to avoid it (although the reasons Måns' gives are better).


Adding even further to this, comparing if a pointer is inside a range
in a portable manner is going to be very slow.

The obvious, and unportable, solution is to use something like:

if (pointer <= range_start && pointer > range_end)
; /* pointer is inside */
else
; /* pointer is outside */

This will invoke undefined behavior if pointer is outside the range. See
C99 section 6.5.8 paragraph 5.

The only portable solution is to compare for equality for each location
inside the range, e.g.

for (p = range_start; p < range_end; ++p) {
if (pointer == p)
break;
}
if (p == range_end)
; /* pointer is outside */
else
; /* pointer is inside */

--
mail1dotstofanetdotdk
Måns Rullgård

2004-12-16, 7:45 pm

Bjorn Reese <see@signature> writes:

> Rich Teer wrote:
>
>
> Adding even further to this, comparing if a pointer is inside a range
> in a portable manner is going to be very slow.
>
> The obvious, and unportable, solution is to use something like:
>
> if (pointer <= range_start && pointer > range_end)


Shouldn't that be the other way around?

--
Måns Rullgård
mru@inprovide.com
Dmitry Karasik

2004-12-16, 7:45 pm

NNTP-Posting-Host: balder.adm.ku.dk
Mime-Version: 1.0
Content-Type: text/plain; charset="koi8-r"
Content-Transfer-Encoding: 8bit
X-Trace: news.net.uni-c.dk 1103056919 32133 130.225.126.143 (14 Dec 2004 20:41:59 GMT)
X-Complaints-To: usenet@news.net.uni-c.dk
NNTP-Posting-Date: Tue, 14 Dec 2004 20:41:59 +0000 (UTC)
Keywords: 2001334874
X-Comment-To: Måns Rullgård
X-Newsreader: Gnus v5.7/Emacs 20.7
Cache-Post-Path: plab!unknown@plab
X-Cache: nntpcache 3.0.1 (see http://www.nntpcache.org/)
Cache-Post-Path: balder.adm.ku.dk!unknown@plab.ku.dk
X-Cache: nntpcache 3.0.1 (see http://www.nntpcache.org/)
Xref: number1.nntp.dca.giganews.com comp.unix.programmer:152995

Hi Måns!

On 14 Dec 04 at 16:39, "Måns" (Måns Rullgård) wrote:

Måns> "Bryan Bullard" <replay@to.group.com> writes:[vbcol=seagreen]

Måns> Noooo. Don't do it. If the pointer is invalid, chances are there
Måns> is a bug somewhere that has already trashed enough of you memory
Måns> that even calling fopen() might crash. Even if you manage to read
Måns> enough to find out the pointer is bad, what will you do about it?
Måns> It's much better to just let the program receive a SIGSEGV and dump
Måns> core.

Måns> I have said it before, and I will say it again: unless a pointer is
Måns> *known* to be good, there is *no* way to validate it, and, even if
Måns> there were, there would be *nothing* you could sensibly do at that
Måns> point.

There is a valid point for all of this. For example, gdb manages to
tell valid pointers from invalid, apparently by parsing the executable
file, so if the intention is to write a debugger, I think it is a bit early
to disqualify the question.

I find it hard to find a quick and precise answer how does gdb do this, but
I think it is not far from truth that it is done with the help of libbfd.

--
Sincerely,
Dmitry Karasik

---
catpipe Systems ApS
*BSD solutions, consulting, development
www.catpipe.net
+45 7021 0050
Måns Rullgård

2004-12-16, 7:45 pm

Dmitry Karasik <dmitry@karasik.eu.org> writes:

> Hi Mµns!


Now that's a new way of spelling my name. Is your Emacs perhaps not
MULE enabled?

> On 14 Dec 04 at 16:39, "Mµns" (Mµns Rullgµrd) wrote:
>
> Mµns> "Bryan Bullard" <replay@to.group.com> writes:
>
> Mµns> Noooo. Don't do it. If the pointer is invalid, chances are there
> Mµns> is a bug somewhere that has already trashed enough of you memory
> Mµns> that even calling fopen() might crash. Even if you manage to read
> Mµns> enough to find out the pointer is bad, what will you do about it?
> Mµns> It's much better to just let the program receive a SIGSEGV and dump
> Mµns> core.
>
> Mµns> I have said it before, and I will say it again: unless a pointer is
> Mµns> *known* to be good, there is *no* way to validate it, and, even if
> Mµns> there were, there would be *nothing* you could sensibly do at that
> Mµns> point.
>
> There is a valid point for all of this. For example, gdb manages to
> tell valid pointers from invalid, apparently by parsing the
> executable file, so if the intention is to write a debugger, I think
> it is a bit early to disqualify the question.


The OP was asking for equivalents of some win32 functions that
validate a pointer in the context of the calling process. The
information they return is never, under any circumstance, useful. All
those functions accomplish are encourage bad programming style.

A debugger needs to examine the memory of another process, which is
another thing entirely. Besides, anyone writing a debugger should
probably not need to ask that question in the first place.

Jim Cochrane

2004-12-16, 7:45 pm

In article <84ekhsehix.fsf@plab.ku.dk>, Dmitry Karasik wrote:
> Hi Måns!
>
> On 14 Dec 04 at 16:39, "Måns" (Måns Rullgård) wrote:
>
> Måns> "Bryan Bullard" <replay@to.group.com> writes:
>
> Måns> Noooo. Don't do it. If the pointer is invalid, chances are there
> Måns> is a bug somewhere that has already trashed enough of you memory
> Måns> that even calling fopen() might crash. Even if you manage to read
> Måns> enough to find out the pointer is bad, what will you do about it?
> Måns> It's much better to just let the program receive a SIGSEGV and dump
> Måns> core.
>
> Måns> I have said it before, and I will say it again: unless a pointer is
> Måns> *known* to be good, there is *no* way to validate it, and, even if
> Måns> there were, there would be *nothing* you could sensibly do at that
> Måns> point.
>
> There is a valid point for all of this. For example, gdb manages to


Good pun. :-)

> tell valid pointers from invalid, apparently by parsing the executable
> file, so if the intention is to write a debugger, I think it is a bit early
> to disqualify the question.
>
> I find it hard to find a quick and precise answer how does gdb do this, but
> I think it is not far from truth that it is done with the help of libbfd.
>



--
Jim Cochrane; jtc@dimensional.com
[When responding by email, include the term non-spam in the subject line to
get through my spam filter.]
Bryan Bullard

2004-12-16, 7:45 pm


"Dmitry Karasik" <dmitry@karasik.eu.org> wrote in message
news:84ekhsehix.fsf@plab.ku.dk...
> Hi Måns!
>
> On 14 Dec 04 at 16:39, "Måns" (Måns Rullgård) wrote:
>
> Måns> "Bryan Bullard" <replay@to.group.com> writes:
>
> Måns> Noooo. Don't do it. If the pointer is invalid, chances are there
> Måns> is a bug somewhere that has already trashed enough of you memory
> Måns> that even calling fopen() might crash. Even if you manage to read
> Måns> enough to find out the pointer is bad, what will you do about it?
> Måns> It's much better to just let the program receive a SIGSEGV and dump
> Måns> core.


Yep. Your right.

Thanks.

....


Michel Bardiaux

2004-12-16, 7:45 pm

Bryan Bullard wrote:
> "Dmitry Karasik" <dmitry@karasik.eu.org> wrote in message
> news:84ekhsehix.fsf@plab.ku.dk...
>
>
>
> Yep. Your right.


I agree that if there is a bad pointer, rooting it out :-) is a
priority. However, there is *some* use for validating pointers: during
the debugging itself. Suppose you're running a test harness. You know
that the problem is that at some point some piece of, say, a b-tree, is
clobbered. One possibility is to pepper your code with calls to a
vaidation function that will attempt to verify the tree, and report in
detail as soon as the clobbering occurs, *then* abort. One could of
course simply dereference every known pointer location, but if you know
the bad pointer is 0x20202020 that is a clue worth printing out.

>
> Thanks.
>
> ...
>
>



--
Michel Bardiaux
Peaktime Belgium S.A. Bd. du Souverain, 191 B-1160 Bruxelles
Tel : +32 2 790.29.41
Måns Rullgård

2004-12-16, 7:45 pm

Michel Bardiaux <michel.bardiaux@peaktime.be> writes:

> Bryan Bullard wrote:
>
> I agree that if there is a bad pointer, rooting it out :-) is a
> priority. However, there is *some* use for validating pointers: during
> the debugging itself. Suppose you're running a test harness. You know
> that the problem is that at some point some piece of, say, a b-tree,
> is clobbered. One possibility is to pepper your code with calls to a
> vaidation function that will attempt to verify the tree, and report in
> detail as soon as the clobbering occurs, *then* abort. One could of
> course simply dereference every known pointer location, but if you
> know the bad pointer is 0x20202020 that is a clue worth printing out.


I am still insisting that checking whether an address lies within a
mapped region is totally useless. If it does not, your program will
anyway dump core immediately, and if it does, you are no closer to
finding your bug. To debug memory errors, use something like
valgrind, which will notify you at the moment the error occurs,
instead of when the effects of it become visible.

--
Måns Rullgård
mru@inprovide.com
Bryan Bullard

2004-12-16, 7:45 pm


"Bryan Bullard" <replay@to.group.com> wrote in message
news:Xlnvd.39619$bP2.34471@newssvr12.news.prodigy.com...
>
> "Rich Teer" <rich.teer@rite-group.com> wrote in message
> news:Pine.SOL.4.58.0412102128420.3239@zaphod...
> fault.
my[vbcol=seagreen]
> On systems that page-out memory to some type of device, on each page fault
> the kernel would need to know what to do to handle the page fault. The
> address value is the only metric to determine the next course of action.
> The kernel would need to test the range not only to determine if mapping

in
> a page would be a legal action but where to load that page from (e.g.,

from
> the swap space, from an executable binary image if a code segment, from a
> parent process during a fork, etc ...).
>


Rich,

Actually, on second thought, your are partly right and I am partly wrong.
The address value is not the only metric for the kernel to determine the
next course of action when a page fault is signaled. For example, on the
AI-32 a page fault generates an error code that specifies the environment of
the page fault such as if the fault occurred because the page was not
present or there was a protection violation (among others). However, the
kernel must know the fault address so that it can look up the entry for that
page in the correct page table.

Bryan


Bjorn Reese

2004-12-16, 7:45 pm

Måns Rullgård wrote:
> Bjorn Reese <see@signature> writes:


>
>
> Shouldn't that be the other way around?


Whoops, my bad.


--
mail1dotstofanetdotdk
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com