From: Frank Kotler on
"T.M. Sommers" wrote:
>
> Frank Kotler wrote:
> >
> > Oh, my! I cobbed together a "nanosleep", which may not be
> > right, but at least it assembles. Running the result gives
> > me "Bus Error". That's a new one on me (*told* ya I had a
> > lot to learn about this stuff!).
>
> Bus errors usually mean that the program has tried to access an
> invalid memory location, as opposed to a valid memory location
> that you do not have permission to access, which gives a
> segmentation fault. The most common cause is trying to
> dereference a null pointer, but it could also be caused by a
> misaligned access.

Okay, that helps... The memory I'm trying to access is
around 0x40100000 - that's what mmap returns. It seems as
if, if I map it as "MAP_PRIVATE" instead of "MAP_SHARED",
the problem goes away...

I'm doing my experimentation in Nasm - HLA syntax is just
*too* unintuitive to me :(

Here's what I've got...

global _start

section .data
filename db 'mmaptest.dat', 0

section .text
_start:
nop

mov eax, 5 ; __NR_open
mov ebx, filename
mov ecx, 2 | 100q | 1000q ; O_DRWR, O_CREAT, O_TRUNC
mov edx, 666q
int 80h
or eax, eax
js exit

push byte 0
push eax
; push byte 2 ; MAP_PRIVATE this works
push byte 1 ; MAP_SHARED bus error
push byte 7 ; PROT_READ | PROT_WRITE | PROT_EXEC
push 1000h ; size
push byte 0

mov ebx, esp
mov eax, 90 ; __NR_mmap
int 80h
; call showeax ; for debugging... 0x40000000
mov byte [eax], 'A'

exit:
mov ebx, eax
mov eax, 1
int 80h

When I say this "works" with "MAP_PRIVATE"... it doesn't get
the bus error - I don't actually see the 'A' in my file.
That's expected, I guess, without "MAP_SHARED" (?)...

Here's my HLA "version"...


program statusConsole;
#include( "stdlib.hhf" )
#include( "console.hhf" )
// #include( "w.hhf" )
#include ( "linux.hhf" )
#include( "statusConsole.hhf" )


static
statusStr :string;

shared :pSharedData_t;
mmFile :mmap;


begin statusConsole;

// The statusConsole program, which must be run first,
// is responsbile for creating the memory-mapped file
// in the file system:

mmFile.create();
mmFile.openNew
(
"advGameSharedData.dat",
@max( @size( sharedData_t ), 4096)
);
mov( mmFile.filePtr, eax );
mov( eax, shared );

// Zero out the shared memory area:

mov( eax, edi );
xor( eax, eax );
mov( @size( sharedData_t ), ecx );
rep.stosb();

// Initialize the string pointers into the shared data
area.
// The call to str.init initializes the string you pass
// as the first parameter to the length specified by the
// second parameter. This function returns a pointer to
// the string data that you should store into a local
// STRING variable to use to manipulate that string.

mov( shared, ebx );
str.init( sharedEBX.statusString, 256 );
mov( eax, statusStr );


// Sit in a loop, forever updating the console info

forever

mov( shared, ebx );

// Clearing the screen causes flicker, so you
// may want to do something else here:

console.cls();

// Position the cursor and display the status
// string:

console.gotoxy( 0, 0 );
stdout.put( statusStr );

// Position the cursor and display the current
score:

console.gotoxy( 0, 10 );
stdout.put( "Current Score: ",
sharedEBX.currentScore );

// Update the display once every 500 ms:

// w.Sleep( 500 );

// Okay, I think I'm sleeping 500000 seconds here
// should be pushed in the opposite order
// doesn't matter - we crash first anyway :)
// leave it out, for now...

// mov ( 0, ebx);
// push (ebx);
// mov ( 500000, ebx);
// push ( ebx );
// mov ( 162, eax);
// mov ( esp, ebx );
// mov ( esp, ecx);
// int ( $80 );
// linux.nanosleep( esp, esp );

endfor;

end statusConsole;


And here's what strace thinks of it...

execve("./statusconsole", ["statusconsole"], [/* 36 vars
*/]) = 0
sigaction(SIGSEGV, {0x8048b8c, [], SA_SIGINFO}, NULL,
0x4013f9a0) = 0
sigaction(SIGTRAP, {0x8048bc1, [], SA_SIGINFO}, NULL,
0x4013f9a0) = 0
sigaction(SIGILL, {0x8048be7, [], SA_SIGINFO}, NULL,
0x4013f9a0) = 0
sigaction(SIGFPE, {0x8048c0d, [], SA_SIGINFO}, NULL,
0x4013f9a0) = 0
old_mmap(NULL, 1048576, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x40000000
open("advGameSharedData.dat", O_RDWR|O_CREAT|O_TRUNC, 0600)
= 3
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0)
= 0x40100000
--- SIGBUS (Bus error) ---
+++ killed by SIGBUS +++

I don't know why strace calls it "old_mmap"... It's the only
mmap I'm aware of... no matter...

The first "mmap" works - the filename is copied to the area
just under 0x40100000 before the "open" (I'm not sure
why...). That's what gave me the clue to try
"MAP_PRIVATE"...

The SIGBUS occurs when trying to "stosb" to the newly
mmapped area (0x40100000)...

That's my current state of mystification...

Best,
Frank
From: Charles A. Crayne on
On Fri, 27 May 2005 14:43:23 -0400
Frank Kotler <fbkotler(a)comcast.net> wrote:

:It seems as
:if, if I map it as "MAP_PRIVATE" instead of "MAP_SHARED",
:the problem goes away...

I solved a similar problem by using mmap2 (192) instead of the old mmap
call.

-- Chuck
From: Frank Kotler on
"Charles A. Crayne" wrote:
>
> On Fri, 27 May 2005 14:43:23 -0400
> Frank Kotler <fbkotler(a)comcast.net> wrote:
>
> :It seems as
> :if, if I map it as "MAP_PRIVATE" instead of "MAP_SHARED",
> :the problem goes away...
>
> I solved a similar problem by using mmap2 (192) instead of the old mmap
> call.

Oh, oh! My unistd.h only goes up to 190! That's why strace
calls it "old_mmap", I guess. An attempt to use 192 anyway
returns ENOSYS... I guess unistd.h and man(2) are right.

Is the ability to mmap a file like we're trying to do a
"recent" feature? Yet *another* reason why I've got do do
that upgrade... really, fairly soon now...

Thanks for the suggestion, Chuck - that may be it.

Best,
Frank
From: Charles A. Crayne on
On Fri, 27 May 2005 16:44:27 -0400
Frank Kotler <fbkotler(a)comcast.net> wrote:

:My unistd.h only goes up to 190!

Mine goes to 277! What kernel are you running?

-- Chuck
From: Frank Kotler on
"Charles A. Crayne" wrote:
>
> On Fri, 27 May 2005 16:44:27 -0400
> Frank Kotler <fbkotler(a)comcast.net> wrote:
>
> :My unistd.h only goes up to 190!
>
> Mine goes to 277! What kernel are you running?

2.2.19 - We're up to 2.6.xx these days, eh? Well... I'll get
to it... Although... another 87 syscalls to learn? I haven't
learned the first 190 yet! Maybe I'll just leave well enough
alone :)

Best,
Frank