Mike McCormack wrote:
Two 16bit programs launch, one after the other. Each program hooks INT 0, however since our interrupt tables are global to all tasks, the second task retrieves the interrupt vector that the first task set.
The first task exits, and restores the original INT 0 vector. When the second task exits, tries to restore the INT 0 vector set by the first task, which now has an invalid selector, so it crashes.
After a bit of discussion and writing a test program, we discovered that it appears that some interrupt vectors are task local, and some are global. The local ones appear to be stored in the TDB (task descriptor block), in offsets 0x26 - 0x4a.
The attached patch fixes this, though we're not sure that it is correct for DOS programs.
Well, I don't know much about the relation between Win16 tasks and DOS. If this is how interrupt vectors are handled under Win16 then I guess the basic idea in the patch is correct.
However, I can't see why this would cause a crash because as far as I know, int 0 vector is never called by Wine. It doesn't really matter but I'm just curious... (Perhaps they handle int 0 as a call chain?)
Anyway, this patch fails to initialize the vectors so any attempt to use them causes a crash. These vectors are not currently used by Wine (except 0x3e) so this is not yet a problem but I would really like to see this patch changed so that those vectors are properly initialized (possibly lazily) at program startup and when new task is created (are they copied from another task or reset to default values?).
And, I don't think TASK_GetCurrent() should be called from winedos and I thought use of WINE_PACKED was unnecessary and deprecated.
Jukka Heinonen jhei@iki.fi writes:
However, I can't see why this would cause a crash because as far as I know, int 0 vector is never called by Wine. It doesn't really matter but I'm just curious... (Perhaps they handle int 0 as a call chain?)
It never gets called, but in order to change the vector with int21/ah=25 the vector must be loaded in %ds:%dx. So when the app tries to restore the previous vector it crashes on the %ds selector load because the code segment containing the vector has been freed.
Anyway, this patch fails to initialize the vectors so any attempt to use them causes a crash. These vectors are not currently used by Wine (except 0x3e) so this is not yet a problem but I would really like to see this patch changed so that those vectors are properly initialized (possibly lazily) at program startup and when new task is created (are they copied from another task or reset to default values?).
Well, the patch is doing a kind of lazy initialisation, since it falls back to the global vector if the task one is 0. We could possibly set the task vector at that point, but it's not clear to me that it would be necessary.
On Tue, Oct 07, Alexandre Julliard wrote:
Well, the patch is doing a kind of lazy initialisation, since it falls back to the global vector if the task one is 0. We could possibly set the task vector at that point, but it's not clear to me that it would be necessary.
Now that you mention it, the patch indeed does lazy intialization. I really should try to avoid doing anything that requires thinking when I'm tired... So, patch looks correct, after all and I don't think setting task vectors would be useful, either.