I'm trying to make the dedicated server of Gusanos (gusanos.sf.net) run on a SuSE 9.1 root server. While doing that I found out, that Allegro can't initialize the system driver, for whatever reason. I then tried running some of the test applications in the Allegro dir, and they all fail, too.
I tried stepping through allegro_init() with GDB but using a debugger on command line is pain in the a**
This is what allegro_error holds after allegro_init():
VT_GETSTATE: Invalid argument
This is the end of the strace output:
1 | close(4) = 0 |
2 | fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 |
3 | stat64("/dev/tty1", {st_mode=S_IFCHR|0660, st_rdev=makedev(4, 1), ...}) = 0 |
4 | stat64("/dev/tty2", {st_mode=S_IFCHR|0660, st_rdev=makedev(4, 2), ...}) = 0 |
5 | stat64("/dev/tty3", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 3), ...}) = 0 |
6 | stat64("/dev/tty4", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 4), ...}) = 0 |
7 | stat64("/dev/tty5", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 5), ...}) = 0 |
8 | stat64("/dev/tty6", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 6), ...}) = 0 |
9 | stat64("/dev/tty7", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 7), ...}) = 0 |
10 | stat64("/dev/tty8", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 8), ...}) = 0 |
11 | stat64("/dev/tty9", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 9), ...}) = 0 |
12 | stat64("/dev/tty10", {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 10), ...}) = 0 |
13 | stat64("/dev/tty11", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 11), ...}) = 0 |
14 | stat64("/dev/tty12", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 12), ...}) = 0 |
15 | stat64("/dev/tty13", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 13), ...}) = 0 |
16 | stat64("/dev/tty14", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 14), ...}) = 0 |
17 | stat64("/dev/tty15", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 15), ...}) = 0 |
18 | stat64("/dev/tty16", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 16), ...}) = 0 |
19 | stat64("/dev/tty17", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 17), ...}) = 0 |
20 | stat64("/dev/tty18", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 18), ...}) = 0 |
21 | stat64("/dev/tty19", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 19), ...}) = 0 |
22 | stat64("/dev/tty20", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 20), ...}) = 0 |
23 | stat64("/dev/tty21", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 21), ...}) = 0 |
24 | stat64("/dev/tty22", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 22), ...}) = 0 |
25 | stat64("/dev/tty23", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 23), ...}) = 0 |
26 | stat64("/dev/tty24", 0xbfffefac) = -1 ENOENT (No such file or directory) |
27 | open("/dev/console", O_WRONLY) = 4 |
28 | ioctl(4, VT_GETSTATE, 0xbffff1b6) = -1 EINVAL (Invalid argument) |
29 | close(4) = 0 |
30 | fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 |
31 | mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4056a000 |
32 | write(1, "VT_GETSTATE: Invalid argument\n", 30VT_GETSTATE: Invalid argument |
33 | ) = 30 |
34 | munmap(0x4056a000, 4096) = 0 |
35 | exit_group(0) = ? |
36 | Process 20117 detached |
Allegro was compiled with "--without-x" so it should only use the Linux console driver. Can anyone intimate enough with the Linux port tell me what is causing the trouble here?
Of course.
There are two ways to run allegro compiled without X support under X:
1. init allegro using install_allegro(SYSTEM_NONE, &errno, atexit)
- you will not be able to use any system dependent allegro API: timers, rest(), keyboard, mouse ..., only memory bitmaps and config file routines (maybe even something else)
2. grab the latest SVN version and allegro will init fine.
- when you try to init something that requires a linux console (GFX, keyboard) it will fail because you need to be root for that from X. Timer, sound and mouse will work fine.
The third way is to run your allegro program as root.
I was root. I'll try the SVN version.
Edit: Ok. 4.2 branch does this:
1 | stat64("/dev/tty19", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 19), ...}) = 0 |
2 | stat64("/dev/tty20", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 20), ...}) = 0 |
3 | stat64("/dev/tty21", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 21), ...}) = 0 |
4 | stat64("/dev/tty22", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 22), ...}) = 0 |
5 | stat64("/dev/tty23", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 23), ...}) = 0 |
6 | stat64("/dev/tty24", 0xbffff21c) = -1 ENOENT (No such file or directory) |
7 | open("/dev/console", O_WRONLY) = 7 |
8 | ioctl(7, 0x5603, 0xbffff456) = -1 EINVAL (Invalid argument) |
9 | close(7) = 0 |
10 | rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0 |
11 | write(5, "@\332\4@\0\0\0\0\0\0\0\0p\t\f\10\0\0\0\0\0\0\0\200\0\0"..., 148) = 148 |
12 | rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0 |
13 | rt_sigsuspend([] <unfinished ...> |
14 | --- SIGRTMIN (Unknown signal 32) @ 0 (0) --- |
15 | <... rt_sigsuspend resumed> ) = -1 EINTR (Interrupted system call) |
16 | sigreturn() = ? (mask now [RTMIN]) |
17 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
18 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
19 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
20 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
21 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
22 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
23 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
24 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
25 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
26 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
27 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
28 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
29 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
30 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
31 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
32 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
33 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
34 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
35 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
36 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
37 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
38 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
39 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
40 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
41 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
42 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
43 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
44 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
45 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
46 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
47 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
48 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
49 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
50 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
51 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
52 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
53 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
54 | ioctl(-1, 0x5607, 0) = -1 EBADF (Bad file descriptor) |
55 | ... <- infinite loop |
Result from 4.3 branch:
1 | stat64("/dev/tty18", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 18), ...}) = 0 |
2 | stat64("/dev/tty19", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 19), ...}) = 0 |
3 | stat64("/dev/tty20", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 20), ...}) = 0 |
4 | stat64("/dev/tty21", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 21), ...}) = 0 |
5 | stat64("/dev/tty22", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 22), ...}) = 0 |
6 | stat64("/dev/tty23", {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 23), ...}) = 0 |
7 | stat64("/dev/tty24", 0xbffff20c) = -1 ENOENT (No such file or directory) |
8 | open("/dev/console", O_WRONLY) = 5 |
9 | ioctl(5, VT_GETSTATE, 0xbffff406) = -1 EINVAL (Invalid argument) |
10 | close(5) = 0 |
11 | mmap2(NULL, 2101248, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40386000 |
12 | mprotect(0x40386000, 4096, PROT_NONE) = 0 |
13 | clone(child_stack=0x40586504, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEART |
14 | ID, parent_tidptr=0x40586bf8, {entry_number:6, base_addr:0x40586bb0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_prese |
15 | nt:0, useable:1}, child_tidptr=0x40586bf8) = 31671 |
16 | mmap2(NULL, 2101248, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40587000 |
17 | mprotect(0x40587000, 4096, PROT_NONE) = 0 |
18 | clone(child_stack=0x40787504, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEART |
19 | ID, parent_tidptr=0x40787bf8, {entry_number:6, base_addr:0x40787bb0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_prese |
20 | nt:0, useable:1}, child_tidptr=0x40787bf8) = 31672 |
21 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
22 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
23 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
24 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
25 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
26 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
27 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
28 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
29 | ioctl(-1, VIDIOC_S_COMP or VT_WAITACTIVE, 0) = -1 EBADF (Bad file descriptor) |
30 | ... |
Why does your server program need Allegro?
IMHO, the question is not really why do he needs it, but why it crash.
And I'm sorry to tell you that I don't see why.
Allegro is needed for the timers and of course image loading/manipulation. I see that latter is possible with SYSTEM_NONE, but former is not.
Also I'd like to mention that it is not MY server, I'm just trying to make it run. Gusanos is opensource and I am trying to set up a dedicated server for it.
Let's focus on 4.2 SVN version.
First, your program tries to init a console. It means it is trying to init keyboard, graphics or something else that requires a linux console. You cannot expect it to work without root permisions from X. I don't know why it doesn't work as root. Even if it would work (and in fact, it should) you would be switched to a console. You wouldn't like it I guess.
Check if it even runs from a real linux console. Are you using a framebuffer device?
Anyway, if you need allegro for your server, do you need graphics and keyboard? I guess you don't. If you don't need even timer functions you can use install_allegro(SYSTEM_NONE, &errno, atexit) instead.
For the record, this is a rented, dedicated root server without X, without monitor, just remote access through SSH. There is no framebuffer device either.
And I do need timers.
Oh, I see. I made some wrong assumptions.
That's strange. Allegro is not supposed to open console in allegro_init. I don't find strace output very descriptive. Does the strace output of 4.2 SVN belong to allegro_init? If I read it well, it doesn't return but it's stuck.
[edit]
It dawned on me: when running from a ssh console the same restrictions apply as running form X. But again, 4.2 SVN shouldn't try to init console in allegro_init().
You could use Linux timers (the way Allegro does) and ditch allegro.... Allegro really isn't meant nor needed for dedicated server programs - all they should do is process, not do that much graphics manip.
There are some features that can be handy on dedicated servers: timers, config file routines, maybe fixed point number routines... Even bitmap handling functions of the games uses pixel based collision detection etc.
Exactly. And as I said two times now, it is not my game, and I have no intention to change anything larger than one or two lines in the code. The game has a dedicated server, and it uses Allegro. So it is either going to work with Allegro, or not at all.
All strace output is from allegro_init(), and you saw that correctly, it gets stuck somewhere during allegro_init() and never returns from that function (with 4.2 branch)
Edit: Oh forget what I said, I assumed allegro's mathtest program wasn't using graphics at all. As it turns out, the endless loop occurs when trying to set a gfx mode or something. Gusanos dedicated starts fine with Allegro SVN 4.2
Hmm...
Have you tried using install_allegro instead ?
EDIT:
I think this passage of the manual sounds good for you:
The available system ID codes will vary from one platform to another, but you will almost always want to pass SYSTEM_AUTODETECT. Alternatively, SYSTEM_NONE installs a stripped down version of Allegro that won't even try to touch your hardware or do anything platform specific: this can be useful for situations where you only want to manipulate memory bitmaps, such as the text mode datafile tools or the Windows GDI interfacing functions.
GullRaDriel: he needs timers
Jörg Rüppel: Hurray! However, set_gfx_mode should be fixed to return -1.