SIGSEGV with ncurses and Far Pointer access

I’m trying to write a short program to monitor and allow changes to the
registers for the parallel ports. I create a short far pointer with
MK_FP(), and I am trying to use ncurses to display the info.

I have successfully access BIOS memory with the far pointer to find the
port addresses of all the parallel ports and used printf’s to write the
information I got out of the BIOS memory area. I did this by itself in
a program and it works.

I also wrote an ncurses program that did nothing but write info to the
screen, and it works.

But when I combine them, first getting the port address from the far
pointer, and then trying to initscr() and do ncurses calls, the program
gets a memory violation SIGSEGV error. If I comment out all the ncurses
stuff from initscr() on, the program doesn’t crash. Or if I comment out
the far pointer code, and leave the ncurses, no crash. Why can’t I use
them together?

Anyone have any ideas?

Scott

J. Scott Franko <jsfranko@switch.com> wrote:

I’m trying to write a short program to monitor and allow changes to the
registers for the parallel ports. I create a short far pointer with
MK_FP(), and I am trying to use ncurses to display the info.

I have successfully access BIOS memory with the far pointer to find the
port addresses of all the parallel ports and used printf’s to write the
information I got out of the BIOS memory area. I did this by itself in
a program and it works.

I also wrote an ncurses program that did nothing but write info to the
screen, and it works.

But when I combine them, first getting the port address from the far
pointer, and then trying to initscr() and do ncurses calls, the program
gets a memory violation SIGSEGV error. If I comment out all the ncurses
stuff from initscr() on, the program doesn’t crash. Or if I comment out
the far pointer code, and leave the ncurses, no crash. Why can’t I use
them together?

Anyone have any ideas?

Do you do any qnx_segment_* calls? Some of these can lock the size
of your data segment – which can cause malloc() to fail to grow your
data segment, and it is very likely that initscr() is trying to allocate
some structures (and isn’t being careful about checking the return on
malloc).

Or, do you try to pass a far pointer to a library routine? Most will
not expect a far pointer, and not will not behave in a reasonable manner.

(I’m assuming this is QNX4.)

-David

QNX Training Services
dagibbs@qnx.com

Here’s the screen output complete with a cat of this short program, and its
SIGSEGV. It doesn’t do much. Can you tell me if I am doing anything to cause
the program to crash? I’m not passing far pointers, and I don’t appear to be
making segment calls. Does this MK_FP macro do something funny to limit the
segment’s growth? Can you tell me another way to get this info from address
0x408?

Scott

$ export LDFLAGS="-lncurses -T 1"
$ make getports
cc -lncurses -T 1 getports.c -o getports
/usr/watcom/10.6/bin/wcc386 -zq -ms -4r -i=/usr/watcom/10.6/usr/include
-i=/usr/include getports.c
/usr/watcom/10.6/bin/wlink op quiet form qnx flat na getports op priv=1 op c
libp /usr/watcom/10.6/usr/lib:/usr/lib:. l /usr/wat
com/10.6/usr/lib/ncurses3r.lib f /home/jsfranko/getports.o op offset=40k op
st=32k
$ su
password:

getports

Port LPT1 is at address 0x278
Port LPT2 is at address 0x0
Port LPT3 is at address 0x0
First parallel port is at 0x278

//9/home/jsfranko/getports terminated (SIGSEGV) at 0005:0000DC2A.
%1 25206 Memory fault getports

cat getports.c

#include <i86.h>
#include <stdio.h>
#include <curses.h>
unsigned short __far *spp_biosaddr;
unsigned short __far *sppaddr[2];
unsigned short __far *spp;

getspps()
{
int p=0;

spp_biosaddr = (unsigned short __far *)MK_FP(0x40, 0x8);

for (p=0; p<3; p++)
{
sppaddr[p] = spp_biosaddr++;
printf(“Port LPT%d is at address 0x%x\n”, p+1, *sppaddr[p]);
}
}

main()
{
getspps();
spp = sppaddr[0];
printf(“First parallel port is at 0x%x\n”, spp);
fflush(stdout);
initscr(); // initialize the curses library
keypad(stdscr, TRUE); // enable keyboard mapping
nonl(); // tell curses not to do NL->CR/NL on output
cbreak(); // take input chars one at a time, no wait for \n
noecho(); // don’t echo input
move(LINES/2 + 1, COLS/2-4);
printw(“Parallel Port 0x%04x”, spp);
refresh(); /
send more output to terminal screen */
endwin();
}

J. Scott Franko <jsfranko@switch.com> wrote:

Here’s the screen output complete with a cat of this short program, and its
SIGSEGV. It doesn’t do much. Can you tell me if I am doing anything to cause
the program to crash? I’m not passing far pointers, and I don’t appear to be
making segment calls. Does this MK_FP macro do something funny to limit the
segment’s growth? Can you tell me another way to get this info from address
0x408?

MK_FP shouldn’t do anything funny – it is purely local. I can’t see
anything that would cause you to crash, at least nothing that looks
wrong to me.

As for getting that infomation – if you know it is at linear address 0x408,
you could do a shm_open( PHYSICAL ), map in the address space, then access
it that way.

I’ll try compiling & running this code here, and see what happens.

-David

QNX Training Services
dagibbs@qnx.com

J. Scott Franko <jsfranko@switch.com> wrote:

Here’s the screen output complete with a cat of this short program, and its
SIGSEGV. It doesn’t do much. Can you tell me if I am doing anything to cause
the program to crash? I’m not passing far pointers, and I don’t appear to be
making segment calls. Does this MK_FP macro do something funny to limit the
segment’s growth? Can you tell me another way to get this info from address
0x408?

Hm… I compile and run this here… no SIGSEGV. It prints out the
4 lines of text (LPT1 is at 0x378 on my machine), then a bunch of
escape/control characters (if I pipe to less) or it clears the screen
and prints near the middle “Parallel Port 0x0008”.

I tried it compiled against the latest in-house, and against 10.6. But,
compiled against the released version, from our tech support server, it
appears to crash. There appears to be a library or compiler problem
somewhere.

I’ve not heard of this problem before – tech support might have.

-David

QNX Training Services
dagibbs@qnx.com

oops, I missed the * on the spp in my printw. It should have just printed Parallel
Port 0x0378. So the compiled against release, it crashes, against inhouse it
works? Which version are you running inhouse?

Are you forwarding this to tech support, or do I need to? I’m don’t have a premium
support contract at this time. What email do I use for support now.

Scott

David Gibbs wrote:

J. Scott Franko <> jsfranko@switch.com> > wrote:
Here’s the screen output complete with a cat of this short program, and its
SIGSEGV. It doesn’t do much. Can you tell me if I am doing anything to cause
the program to crash? I’m not passing far pointers, and I don’t appear to be
making segment calls. Does this MK_FP macro do something funny to limit the
segment’s growth? Can you tell me another way to get this info from address
0x408?

Hm… I compile and run this here… no SIGSEGV. It prints out the
4 lines of text (LPT1 is at 0x378 on my machine), then a bunch of
escape/control characters (if I pipe to less) or it clears the screen
and prints near the middle “Parallel Port 0x0008”.

I tried it compiled against the latest in-house, and against 10.6. But,
compiled against the released version, from our tech support server, it
appears to crash. There appears to be a library or compiler problem
somewhere.

I’ve not heard of this problem before – tech support might have.

-David

QNX Training Services
dagibbs@qnx.com