diff --git a/spec/std/exception/call_stack_spec.cr b/spec/std/exception/call_stack_spec.cr index 1fe31b01ad41..337a678430c2 100644 --- a/spec/std/exception/call_stack_spec.cr +++ b/spec/std/exception/call_stack_spec.cr @@ -57,4 +57,21 @@ describe "Backtrace" do output.to_s.empty?.should be_true error.to_s.should contain("Invalid memory access") end + + pending_win32 "print exception with non-existing PWD" do + source_file = datapath("blank_test_file.txt") + compile_file(source_file) do |executable_file| + output, error = IO::Memory.new, IO::Memory.new + with_tempfile("non-existent") do |path| + Dir.mkdir path + Dir.cd(path) do + # on win32 it seems not possible to remove the directory while we're cd'ed into it + Dir.delete(path) + status = Process.run executable_file + + status.success?.should be_true + end + end + end + end end diff --git a/src/exception/call_stack.cr b/src/exception/call_stack.cr index 536b77bb57d6..498791d97a2b 100644 --- a/src/exception/call_stack.cr +++ b/src/exception/call_stack.cr @@ -13,9 +13,10 @@ struct Exception::CallStack # Compute current directory at the beginning so filenames # are always shown relative to the *starting* working directory. CURRENT_DIR = begin - dir = Process::INITIAL_PWD - dir += File::SEPARATOR unless dir.ends_with?(File::SEPARATOR) - dir + if dir = Process::INITIAL_PWD + dir += File::SEPARATOR unless dir.ends_with?(File::SEPARATOR) + dir + end end @@skip = [] of String diff --git a/src/exception/call_stack/libunwind.cr b/src/exception/call_stack/libunwind.cr index 73852b8b163d..17a784de8f57 100644 --- a/src/exception/call_stack/libunwind.cr +++ b/src/exception/call_stack/libunwind.cr @@ -141,7 +141,9 @@ struct Exception::CallStack next if @@skip.includes?(file) # Turn to relative to the current dir, if possible - file = file.lchop(CURRENT_DIR) + if current_dir = CURRENT_DIR + file = file.lchop(current_dir) + end file_line_column = "#{file}:#{line}:#{column}" end diff --git a/src/process/executable_path.cr b/src/process/executable_path.cr index ed2e7a77722c..5d8062a0d8d6 100644 --- a/src/process/executable_path.cr +++ b/src/process/executable_path.cr @@ -9,7 +9,16 @@ class Process INITIAL_PATH = ENV["PATH"]? # :nodoc: - INITIAL_PWD = Dir.current + # + # Working directory at program start. Nil if working directory does not exist. + # + # Used for `Exception::CallStack::CURRENT_DIR` + # and `Process.executable_path_impl` on openbsd. + INITIAL_PWD = begin + Dir.current + rescue File::NotFoundError + nil + end # Returns an absolute path to the executable file of the currently running # program. This is in opposition to `PROGRAM_NAME` which may be a relative or @@ -166,7 +175,9 @@ end # openbsd, ... class Process private def self.executable_path_impl - find_executable(PROGRAM_NAME, INITIAL_PATH, INITIAL_PWD) + if pwd = INITIAL_PWD + find_executable(PROGRAM_NAME, INITIAL_PATH, pwd) + end end end {% end %}