Home › Forums › TWAIN Classic › Twain support for MEM_TOP_DOWN
- This topic has 7 replies, 2 voices, and was last updated 12 years, 2 months ago by hutdone23.
- AuthorPosts
In our twain library we see an Access Violation exception from within the Twain code. If the machine isn’t large address aware no issue occurs. Twacker64 also crashes if the machine is large address aware.
To enable this set the AllocationPreference key in the registry and restart:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb613473%28v=vs.85%29.aspx
Can this be addressed in new release?
Edit: To clarify the issue is MEM_TOP_DOWN versus LAW
Has anybody else encountered this and if so do you have a workaround?
Do the twain folks have any plans of addressing this in a new release?
I am not sure what you mean by ‘large address aware machine’. Large address awareness is a property of a 32 bit windows process, and not of the machine running it.
Because large address awareness applies to processes, in theory there is nothing TWAIN needs to (or can) do to allow you to write applications that use it in a 32 bit LAW process. It is very clear from all of the literature I’ve read that the large address aware flag has no effect when applied to DLLs. As long as your main application has this flag set, that’s all that should need to happen.
All code whether in a DLL or an application does need to follow some rules in order to work properly with pointers that can go beyond 2GB, but the 32 and 64 bit TWAIN DSM are both built from the same source code and if the rules were not being followed, then the 64 bit DSM would probably crash even on a 64 bit machine with lots of RAM. We have used the 64 bit DSM plenty where I work without any issues, so I don’t think there is an issue with the DSM and pointers > 2GB.
It’s possible that your TWAIN drivers (data sources) are not happy living in a large address aware process, and it’s also possible that even though your process is large address aware, you are trying to allocate too much memory. You should already know if this problem happens because you are trying to allocate > 2GB, and you could try a different scanner from a completely different manufacturer to determine if the issue is in the data source.
There are some cautions when using LAW flag in your application that could be causing a crash:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb613473(v=VS.85).aspx
Of particular note at that page is the statement:
•Addresses near the 2-GB boundary are typically used by various system DLLs. Therefore, a 32-bit process cannot allocate more than 2 GB of contiguous memory, even if the entire 4-GB address space is available.
So if you are hoping that you can simply compile with the LAW flag on and then allocate huge chunks of memory, your assumptions may be wrong. The actual limit of what you can allocate may also be lower than 2GB because by the time you get around to trying to allocate something, you’ve probably already used up a bunch of the lower 2GB, and there is only 1GB of space above the 2GB boundary if this is a 32 bit machine (I’m not really clear on whether you are on a 32 bit machine that has the boot.ini modified to allow 3GB of addressable space or on a 64 bit machine trying to run a 32 bit app).
With regard to Twacker64, it is a native 64 bit application intended to run on a 64 bit operating system with a 64 bit DSM and 64 bit drivers. You should only be using it if all the above are native 64 bit. If your drivers and apps are 32 bit, then you should be using the 32 bit version of Twacker.
I hope this helps.
To clarify:
-I meant my process is LAW, not my machine.
-I’m on a 64-bit machine.
-I’m using Twacker_64.
-I’m using the ‘TWAIN2 FreeImage Software Scanner’ or TWAINDS_Sample64.ds Data Source.
-I’ve typically experienced errors when a process is LAW from pointer truncation occurring, in this case nothing gigantic is being allocated and I believe perhaps as you said the DS isn’t happy.
-In our TWAIN SDK I believe I originally saw the Access Violation occur from the message loop and inspecting the callstack it appeared it was coming from the twain DS. To take our product out of the equation I used Twacker and using the Twacker sample DS.
To reproduce what I’m seeing do the following:
1) Change your registry to make your process LAW and restart as detailed in my original post.
2) Run Twacker_64.exe
3) File->Select Source…
4) Select the TWAIN2 FreeImage Software Scanner, press the Select button
5) Special->1) Load/Open SM
6) Special->2) Open Source
7) Special->4) Enable
8.) Press the scan button on the UI.Twacker_64 crashes.
When I debug into Twacker_64, I see an Access Violation in the message loop of WinMain() of TWACKER.c from the FreeImage library used by the DS:
From the Output Window in Visual Studio:
First-chance exception at 0x100053f0 in Twack_64.exe: 0xC0000005: Access violation writing location 0x00000000fcaa004c.
Unhandled exception at 0x100053f0 in Twack_64.exe: 0xC0000005: Access violation writing location 0x00000000fcaa004c.The Call Stack:
FreeImagex64.dll!00000000100053f0()
[Frames below may be incorrect and/or missing, no symbols loaded for FreeImagex64.dll]
FreeImagex64.dll!000000001000587b()
FreeImagex64.dll!0000000010020297()
FreeImagex64.dll!0000000010008785()
TWAINDS_Sample64.ds!000007fef5e234b7()
TWAINDS_Sample64.ds!000007fef5e3f0d8()
TWAINDS_Sample64.ds!000007fef5e509c7()
TWAINDS_Sample64.ds!000007fef5e454f0()
TWAINDS_Sample64.ds!000007fef5e5ec18()
QtCore4.dll!00000000670d5de3()
QtCore4.dll!00000000670e1b7f()
QtGui4.dll!00000000654e3cc7()
QtGui4.dll!00000000652e0187()
QtGui4.dll!00000000652e13c3()
QtGui4.dll!00000000652e15af()
QtGui4.dll!000000006505da57()
QtGui4.dll!00000000652e05c9()
QtGui4.dll!0000000065019202()
QtGui4.dll!000000006501c55a()
QtCore4.dll!00000000670d0d81()
QtCore4.dll!000000006711d296()
QtGui4.dll!000000006501b9eb()
QtGui4.dll!0000000065071c55()
QtGui4.dll!000000006507482b()
user32.dll!00000000771a9bd1()
user32.dll!00000000771a98da()
> Twack_64.exe!WinMain(HINSTANCE__ * hInstance=0x0000000140000000, HINSTANCE__ * hPrevInstance=0x0000000000000000, char * lpszCmdLine=0x000007ffffd648a8, int CmdShow=1) Line 160 C
Twack_64.exe!__tmainCRTStartup() Line 275 + 0x42 bytes C
Twack_64.exe!WinMainCRTStartup() Line 189 C
kernel32.dll!0000000076d2652d()
ntdll.dll!000000007741c521()Hopefully this paints a better picture of the problem I’m seeing.
The second entry in the first table on the page shown here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx
indicates that 64 bit applications by default are large address aware. This property is inside the executable, not in the registry. When you build a 32 bit app, you have to set the large address aware flag manually, but for 64 bit applications it should be on by default.
From your post, it looks like you’re using a 64 bit driver on a 64 bit OS from a 64 bit application. You shouldn’t have to worry about the large address aware bit. It should be on by default.
The only registry setting I can see on your original link page is a setting to force memory allocations to happen top down instead of bottom up. I’ll try this when I have time someday, but the simple solution is to not force top down allocations. The most RAM you can physically put into a machine currently would not cause the high bit to be set on a 64 bit pointer if you don’t enable that flag.
@peterp wrote:
The second entry in the first table on the page shown here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx
indicates that 64 bit applications by default are large address aware. This property is inside the executable, not in the registry. When you build a 32 bit app, you have to set the large address aware flag manually, but for 64 bit applications it should be on by default.
From your post, it looks like you’re using a 64 bit driver on a 64 bit OS from a 64 bit application. You shouldn’t have to worry about the large address aware bit. It should be on by default.
The only registry setting I can see on your original link page is a setting to force memory allocations to happen top down instead of bottom up. I’ll try this when I have time someday, but the simple solution is to not force top down allocations. The most RAM you can physically put into a machine currently would not cause the high bit to be set on a 64 bit pointer if you don’t enable that flag.
Sorry for miscategorizing the issue or leading anyone astray, MEM_TOP_DOWN is the issue. I edited my original post to reflect this. However I believe the problem of the Access Violation occurring is still a valid issue. I must’ve got caught up in the information on LAW and just cited the link with it out fully understanding the distinction.
Don’t worry about leading anyone astray. I’m just glad things look a bit clearer now.
To recap:
– you’ve found an issue when setting the MEM_TOP_DOWN flag that’s worth looking into
– you should be able to move ahead using 64 bit architecture without setting the top down flagAre you good to go for now?
@peterp wrote:
Don’t worry about leading anyone astray. I’m just glad things look a bit clearer now.
To recap:
– you’ve found an issue when setting the MEM_TOP_DOWN flag that’s worth looking into
– you should be able to move ahead using 64 bit architecture without setting the top down flagAre you good to go for now?
For now that’s the workaround yes, to not set the MEM_TOP_DOWN flag.
- AuthorPosts