noreply at rubyforge.org
2009-Jan-31 12:01 UTC
[Win32utils-devel] [ win32utils-Bugs-23746 ] File.size fails on locked file (and causes major rdebug wierdness)
Bugs item #23746, was opened at 2009-01-29 20:17 You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=411&aid=23746&group_id=85 Category: None Group: None Status: Open Resolution: Accepted Priority: 3 Submitted By: Montgomery Kosma (mkosma) Assigned to: Nobody (None) Summary: File.size fails on locked file (and causes major rdebug wierdness) Initial Comment: Running the following script fails in an ugly fashion. Note that the default File.size does not fail (but it also returns an incorrect result, a negative number). #test.rb require ''win32/file'' x = File.size(''c:/pagefile.sys'') puts x C:\docs\Prog\PSTTools>test.rb c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:586: in `get_file_type'': unknown error - The process cannot access the file because it is being used by another process. (SystemCallError) from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:58:in `initialize'' from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `new'' from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `size'' from C:/docs/Prog/PSTTools/test.rb:3 So I tried to dig into the win32-file source to see where it''s failing -- a size command really shouldn''t need to lock the file. The really puzzling thing is that I cannot successfully run rdebug on this. Even if I set a breakpoint before the call to File.size, rdebug errors out before it arrives. I''m not skilled enough (yet) to determine if this is related to the win32-size bug, or a problem with rdebug (ver 0.10.3). Here''s what happens: C:\docs\Prog\PSTTools>rdebug test.rb C:/docs/Prog/PSTTools/test.rb:1 require ''win32/file'' (rdb:1) list [-4, 5] in C:/docs/Prog/PSTTools/test.rb => 1 require ''win32/file'' 2 3 x = File.size(''c:/pagefile.sys'') 4 puts x 5 (rdb:1) b 3 Breakpoint 1 file C:/docs/Prog/PSTTools/test.rb, line 3 (rdb:1) n INTERNAL ERROR!!! no implicit conversion from nil to integer c:/ruby/lib/ruby/1.8/pathname.rb:269:in `[]'' c:/ruby/lib/ruby/1.8/pathname.rb:269:in `chop_basename'' c:/ruby/lib/ruby/1.8/pathname.rb:322:in `cleanpath_aggressive'' c:/ruby/lib/ruby/1.8/pathname.rb:310:in `cleanpath'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:93:in `canonic_file'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:98:in `print_location_and_text'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:243:in `process_commands'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:171:in `__at_line'' (eval):5:in `at_line'' (eval):3:in `synchronize'' (eval):3:in `at_line'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-base-0.10.3-x86-mswin32/lib/ruby-debug-base.rb:54:in `at_line'' C:/docs/Prog/PSTTools/test.rb:3 c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_load'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_program'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:412 c:/ruby/bin/rdebug:19:in `load'' c:/ruby/bin/rdebug:19 c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:586:in `get_file_type'' c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:58:in `initialize'' c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `new'' c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `size'' C:/docs/Prog/PSTTools/test.rb:3 c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_load'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_program'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:412 c:/ruby/bin/rdebug:19:in `load'' c:/ruby/bin/rdebug:19 Uncaught exception: unknown error - The process cannot access the file because it is being used by another process. ---------------------------------------------------------------------->Comment By: Daniel Berger (djberg96)Date: 2009-01-31 05:01 Message: That will work, thanks. The problem with that approach, however, is that it would result in having two separate implementations - one for File.size, and one for File::Stat#size. The also noticed that GetFileAttributes fails on that file, so it''s double trouble. Maybe I should replace the Win32::File::Stat implementation with one that uses FindFirstFile, since the WIN32_FIND_DATA struct stores attribute information as well. Dan ---------------------------------------------------------------------- Comment By: Park Heesob (phasis68) Date: 2009-01-30 07:30 Message: There are two issues in this error. First, the Standard API function CreateFile cannot open file locked by "System" such as "pagefile.sys". We need other workaround to handle system locked file. Second, the complex stat call is not needed to get only the file size. Here is a usable size method for win32-file: def size(file) # File::Stat.new(file).size buffer = 0.chr * 512 h = FindFirstFile(file,buffer) if h == INVALID_HANDLE_VALUE raise SystemCallError,get_last_error() end FindClose(h) (buffer[28,4].unpack(''L'').first << 32) + buffer[32,4].unpack(''L'').first end Regards, Park Heesob ---------------------------------------------------------------------- You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=411&aid=23746&group_id=85
noreply at rubyforge.org
2009-Jan-31 13:40 UTC
[Win32utils-devel] [ win32utils-Bugs-23746 ] File.size fails on locked file (and causes major rdebug wierdness)
Bugs item #23746, was opened at 2009-01-30 12:17 You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=411&aid=23746&group_id=85 Category: None Group: None Status: Open Resolution: Accepted Priority: 3 Submitted By: Montgomery Kosma (mkosma) Assigned to: Nobody (None) Summary: File.size fails on locked file (and causes major rdebug wierdness) Initial Comment: Running the following script fails in an ugly fashion. Note that the default File.size does not fail (but it also returns an incorrect result, a negative number). #test.rb require ''win32/file'' x = File.size(''c:/pagefile.sys'') puts x C:\docs\Prog\PSTTools>test.rb c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:586: in `get_file_type'': unknown error - The process cannot access the file because it is being used by another process. (SystemCallError) from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:58:in `initialize'' from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `new'' from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `size'' from C:/docs/Prog/PSTTools/test.rb:3 So I tried to dig into the win32-file source to see where it''s failing -- a size command really shouldn''t need to lock the file. The really puzzling thing is that I cannot successfully run rdebug on this. Even if I set a breakpoint before the call to File.size, rdebug errors out before it arrives. I''m not skilled enough (yet) to determine if this is related to the win32-size bug, or a problem with rdebug (ver 0.10.3). Here''s what happens: C:\docs\Prog\PSTTools>rdebug test.rb C:/docs/Prog/PSTTools/test.rb:1 require ''win32/file'' (rdb:1) list [-4, 5] in C:/docs/Prog/PSTTools/test.rb => 1 require ''win32/file'' 2 3 x = File.size(''c:/pagefile.sys'') 4 puts x 5 (rdb:1) b 3 Breakpoint 1 file C:/docs/Prog/PSTTools/test.rb, line 3 (rdb:1) n INTERNAL ERROR!!! no implicit conversion from nil to integer c:/ruby/lib/ruby/1.8/pathname.rb:269:in `[]'' c:/ruby/lib/ruby/1.8/pathname.rb:269:in `chop_basename'' c:/ruby/lib/ruby/1.8/pathname.rb:322:in `cleanpath_aggressive'' c:/ruby/lib/ruby/1.8/pathname.rb:310:in `cleanpath'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:93:in `canonic_file'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:98:in `print_location_and_text'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:243:in `process_commands'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:171:in `__at_line'' (eval):5:in `at_line'' (eval):3:in `synchronize'' (eval):3:in `at_line'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-base-0.10.3-x86-mswin32/lib/ruby-debug-base.rb:54:in `at_line'' C:/docs/Prog/PSTTools/test.rb:3 c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_load'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_program'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:412 c:/ruby/bin/rdebug:19:in `load'' c:/ruby/bin/rdebug:19 c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:586:in `get_file_type'' c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:58:in `initialize'' c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `new'' c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `size'' C:/docs/Prog/PSTTools/test.rb:3 c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_load'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_program'' c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:412 c:/ruby/bin/rdebug:19:in `load'' c:/ruby/bin/rdebug:19 Uncaught exception: unknown error - The process cannot access the file because it is being used by another process. ---------------------------------------------------------------------->Comment By: Park Heesob (phasis68)Date: 2009-01-31 22:40 Message: Win32::File::Stat implementation with FindFirst would be better. If you really want to keep the current implementation, you can get the handle of system locked file by the undocumented NtQuerySystemInformation API instead of CreateFile. Refer to http://forum.sysinternals.com/forum_posts.asp?TID=3577 Regards, Park Heesob ---------------------------------------------------------------------- Comment By: Daniel Berger (djberg96) Date: 2009-01-31 21:01 Message: That will work, thanks. The problem with that approach, however, is that it would result in having two separate implementations - one for File.size, and one for File::Stat#size. The also noticed that GetFileAttributes fails on that file, so it''s double trouble. Maybe I should replace the Win32::File::Stat implementation with one that uses FindFirstFile, since the WIN32_FIND_DATA struct stores attribute information as well. Dan ---------------------------------------------------------------------- Comment By: Park Heesob (phasis68) Date: 2009-01-30 23:30 Message: There are two issues in this error. First, the Standard API function CreateFile cannot open file locked by "System" such as "pagefile.sys". We need other workaround to handle system locked file. Second, the complex stat call is not needed to get only the file size. Here is a usable size method for win32-file: def size(file) # File::Stat.new(file).size buffer = 0.chr * 512 h = FindFirstFile(file,buffer) if h == INVALID_HANDLE_VALUE raise SystemCallError,get_last_error() end FindClose(h) (buffer[28,4].unpack(''L'').first << 32) + buffer[32,4].unpack(''L'').first end Regards, Park Heesob ---------------------------------------------------------------------- You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=411&aid=23746&group_id=85