[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::digital_unix

Title:DIGITAL UNIX(FORMERLY KNOWN AS DEC OSF/1)
Notice:Welcome to the Digital UNIX Conference
Moderator:SMURF::DENHAM
Created:Thu Mar 16 1995
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:10068
Total number of notes:35879

9647.0. "semctl(2) returns bad pointer -> is this the right notes conference?" by OZROCK::THOMAN (Just reboot & it will work again ;-)) Tue Apr 29 1997 04:31

	I'm getting a bad pointer returned from semctl(2)	
	function, causing my program to crash. Is this the
	right notes conference to ask questions about this 
	problem ?

	The 1st reply contains the details.

	Thanks,

	Craig.
T.RTitleUserPersonal
Name
DateLines
9647.1My code..OZROCK::THOMANJust reboot & it will work again ;-)Tue Apr 29 1997 04:44240
	D/Unix 3.2

[665] 5:35pm pkdots ~/sii/mqs_and_sems : uname -a
OSF1 pkdots.ozy.dec.com V3.2 148 alpha



	Below is a simplified version of my program.
	It builds with:
		
		$ cxx <file>
		
	& crashes with 

		$ ./a.out 

	;-)
	
	On a machine with the folloing ipcs output 
	for semaphores:

[660] 5:25pm pkdots ~/sii/mqs_and_sems : ipcs -s | sort


Semaphores:
T      ID     KEY      MODE        OWNER    GROUP
s       0 1090534153 --ra-------      root   system
s       7 1091003201 --ra-ra-ra-      root   system
s       8 1090519180 --ra-ra-ra-      root   system
s       9 20808835 --ra-r--r--      root   system
s      10 1845977936 --ra-ra----      root   system
s      11        0 --ra-ra-ra-      root   system
s      19 1359428932 --ra-ra-ra-       dmq    staff
s      20 1359428934 --ra-ra-ra-       dmq    staff
s      21 1359428938 --ra-ra-ra-       dmq    staff
s      22 1359428940 --ra-ra-ra-       dmq    staff
s      33     6732 --ra-------      root   daemon
s      34 1359407575 --ra-ra-ra-       dmq    staff




	When I build & run I see:


[663] 5:32pm pkdots ~/sii/mqs_and_sems : look_sem_basic
SEM: 0 semctl() failed: Permission denied
SEM: 1 semctl() failed: Invalid argument
SEM: 2 semctl() failed: Invalid argument
SEM: 3 semctl() failed: Invalid argument
SEM: 4 semctl() failed: Invalid argument
SEM: 5 semctl() failed: Invalid argument
SEM: 6 semctl() failed: Invalid argument
SEM: 7
  Owner   UID/GID        : 0/0
  Creator UID/GID        : 0/0
  # Sems in {}           : 2
Segmentation fault (core dumped)

	

	The "invalid arguments are from errno 'cause
	there are no semaphores numbered  1 to 6 at
	the current time.

	When the loop reaches 7, the semctl() returns
	0, and I attempt to access the data returned.
	On trying to access the "sem" structure, my 
	program crashes.

	I couldn't find the semun union in any header 
	file, so I typed into my module. It appears in
	the man page for semctl().

	Using the decladebug-ger I see the pointer,
	semDetails.buf->sem_base is fine before the id=7
	call to semctl(), but has the value

		0xfffffc000db47d60

	after the call.

	I run the program as myself, not root.
	
	Thanks for any assistance.

	Craig.
	
				

(ladebug) p *semDetails.buf
struct {
  sem_perm = struct {
    uid = 0;
    gid = 0;
    cuid = 0;
    cgid = 0;
    mode = 0;
    seq = 0;
    key = 0;
  };
  sem_base = 0x140002cc0;
  sem_nsems = 0;
  sem_otime = 0;
  sem_ctime = 0;
}
(ladebug) p *semDetails.buf->sem_base
struct {
  semval = 0;
  sempid = 0;
  semncnt = 0;
  semzcnt = 0;
}
(ladebug) p i
7
(ladebug) n
stopped at [int main(int, char**):110 0x120001f60]
    110         if (sstatus == -1)
(ladebug) p i
7
(ladebug) p *semDetails.buf
struct {
  sem_perm = struct {
    uid = 0;
    gid = 0;
    cuid = 0;
    cgid = 0;
    mode = 33279;
    seq = 0;
    key = 1091003201;
  };
  sem_base = 0xfffffc000db47d60;
  sem_nsems = 2;
  sem_otime = 859531151;
  sem_ctime = 859531130;
}
(ladebug) q





//
// Date	: Tue 29/Apr/1997
//
// Author: CAT
//
// Abstract: Semaphore polling.
//

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <iostream.h>



// 
// Typedefs
//

typedef union semun 
{
    int		      val;
    struct semid_ds  *buf;
    u_short	     *array;
} SemUnion;



//
// Globals
//

int errno;




int 
main( void )
{
    SemUnion	    semDetails;

    int		    i, 
		    sstatus;


    if (!(semDetails.buf = (struct semid_ds *)malloc(sizeof(struct semid_ds))))
    {
	perror("Malloc buf failed: ");
	exit(-1);
    }

    if (!(semDetails.buf->sem_base = (struct sem *)malloc(sizeof(struct sem))))
    {
	perror("Malloc sem_base failed: ");
	exit(-1);
    }
  
    for (i=0; i<=34; i++)
    {
	sstatus = semctl(i, 0, IPC_STAT, semDetails);

	if (sstatus == -1)
	{
	    cout << "SEM: " << i 
		 << " semctl() failed: " << sys_errlist[errno] 
		 << endl;
	}
	else
	{
	    cout << "SEM: " << i << endl
		 << "  Owner   UID/GID        : " 
		 << semDetails.buf->sem_perm.uid  
		 << "/" 
		 << semDetails.buf->sem_perm.gid  << endl
		 << "  Creator UID/GID        : " 
		 << semDetails.buf->sem_perm.cuid 
		 << "/" 
		 << semDetails.buf->sem_perm.cgid << endl
		 << "  # Sems in {}           : " << semDetails.buf->sem_nsems << endl
		 << "  Prcs waiting val > curr: " << semDetails.buf->sem_base->semncnt	<< endl
		 << "  Prcs waiting val = 0   : " << semDetails.buf->sem_base->semzcnt	<< endl
		 << "  PID of last semop()    : " << semDetails.buf->sem_base->sempid	<< endl
		 << "  last semop()           : " << ctime(&semDetails.buf->sem_otime)	<< endl
		 << "  change time            : " << ctime(&semDetails.buf->sem_ctime)	
		 << endl << endl;
	} // end else

    } // end for

} // end main

9647.2Anyone ? Any ideas ? - thx C.OZROCK::THOMANJust reboot &amp; it will work again ;-)Wed Apr 30 1997 05:140
9647.3Need to have read permission (ie. 'root')DECC::SULLIVANJeff SullivanWed Apr 30 1997 18:1427
This does not look like a C++ problem and you appear to be calling semctl()
correctly. See man semctl, under IPC_STAT.

I got the same results as myself, but here's what I see when run as root:

# a.out
SEM: 0
  Owner   UID/GID        : 0/0
  Creator UID/GID        : 0/0
  # Sems in {}           : 1
Segmentation fault
# 

Looks like a little more work is needed...

I also removed your "int errno", you should not need that if you
#include <errno.h>, which you did.

Here's where the crash is:

signal Segmentation fault at   [main:86 +0x20,0x1200029cc]      << "  Prcs
waiting val > curr: " << semDetails.buf->sem_base->semncnt  << endl

Good luck!

-Jeff

9647.4Thanks for ya response..OZROCK::THOMANYoda on C++ to C programmers: &quot;You Must Unlearn What You Have Learned!&quot;Wed Apr 30 1997 21:1233
RE  -.1

>This does not look like a C++ problem and you appear to be calling semctl()
>correctly. 


	That's why I don't know what I'm doing wrong - I don't see anything
	obviously wrong either !


>I got the same results as myself, but here's what I see when run as root:

	I see that same output running as root or as myself.


>Here's where the crash is:
>
>signal Segmentation fault at   [main:86 +0x20,0x1200029cc]      << "  Prcs


	I know.. The crash happens when I access the "sem" struct 
	inside the semid_ds struct. I have no trouble accessing the
	ipc_perm struct which is also inside the semid_ds struct 
	(see sys/sem.h)

	
	I'm in the process of copying over the cxx 5.6 FT kit - I'll
	see if that helps, I'm also going to try the cc compiler.

	
	
	Craig.
9647.5SMURF::SCOTTThu May 01 1997 00:2223
> I know.. The crash happens when I access the "sem" struct 
> inside the semid_ds struct. I have no trouble accessing the
> ipc_perm struct which is also inside the semid_ds struct 
> (see sys/sem.h)

From the semctl(2) manpage, I would guess you need to use the GETNCNT,
GETZCNT, and GETPID options. 

The ipc_perm struct is embedded within the semid_ds structure.  When the
semid_ds struct is copied out to user-space, so is the ipc_perm struct. 
The sem_base field is a pointer to a separate kernel structure.  When you
fetch the semid_ds, all you get is the sem_base *pointer*. 

  struct semid_ds{
          struct ipc_perm sem_perm;
          struct sem *sem_base;
          u_short sem_nsems;
          time_t sem_otime;
          time_t sem_ctime;
  };


Hope this helps.
9647.6RE .5 - Is there a man page interpreter in the house ?OZROCK::THOMANYoda on C++ to C programmers: &quot;You Must Unlearn What You Have Learned!&quot;Thu May 01 1997 02:1741
Re .1.
	
> From the semctl(2) manpage, I would guess you need to use the GETNCNT,
> GETZCNT, and GETPID options. 

	They way I read it is only one of these should be supplied, and
	the value is returned in the "val" field of the union.

	The man page is not clear at all.

	All I want is 1 call to semctl() that populates the semid_ds
	structure, & the 2 structures within it, sem_perm & *sem_base.

	I can't believe it is turning out to be this difficult !

	By calling semctl() like:

		...
		union semun SemDetails;
		
		semctl( ..., ..., IPC_STAT, SemDetails)

	the man page appears to say SemDetails->buf gets populated, 
	thereby ignoring the other fields in the union called 
	"val" & "*array".

	Anyone outthere ever successfully done an semctl IPC_STAT 
	and obtained the PID etc. from sem_base.


	Craig.


	If this is correct, I want to be able to access the fields
	of sem_base. Currently it crashes when I try 'because the
	sem_base pointer is set to an address starting with 0xffff..

	

		
9647.7SMURF::SCOTTThu May 01 1997 10:5816
> 	
> > From the semctl(2) manpage, I would guess you need to use the GETNCNT,
> > GETZCNT, and GETPID options. 
> 
> 	They way I read it is only one of these should be supplied, and
> 	the value is returned in the "val" field of the union.
> 

Yes.  You need to make separate calls to semctl, specifying just a single
option.  To correct your code, you will need to use each of the
above-mentioned options.  For example:

    ncnt = semctl( i, 0, GETNCNT, 0 );

will return the value of semncnt, or -1.

9647.8What inefficiency!!!OZROCK::THOMANYoda on C++ to C programmers: &quot;You Must Unlearn What You Have Learned!&quot;Fri May 02 1997 02:3236

	Re: -.1

	I don't know whether to be happy that you've helped 
	fixed my problem, or sad at the inefficency ! To get 
	all the info there is on 1 semaphore takes ** 4 **
	calls to semctl(). ie:


	SemUnion	    semDetails;
    	int		    i, sstatus, ncnt, zcnt, pid;
	....
	sstatus = semctl(i, 0, IPC_STAT, semDetails);
	if (sstatus == -1)
	{
	   // HandleError
	}
	else
	{
	    ncnt = semctl(i, 0, GETNCNT, 0);
	    zcnt = semctl(i, 0, GETNCNT, 0);
	    pid  = semctl(i, 0, GETPID,  0);

	    // Now I can finaly do the print or whatever
	}


	Obviously the person who invented semctl() isn't
	around to ask questions to.


	** Thanks ** for your input !!


	Craig.