Here's one way to do it:
open STDOUT, ">ls.out" or die "Can't write to ls.out: $!";
open STDERR, ">ls.err" or die "Can't write to ls.err: $!";
chdir "/" or die "Can't chdir to root directory: $!";
exec "ls", "-l" or die "Can't exec ls: $!";
The first and second lines reopen STDOUT and STDERR to a file in the current directory before we change directories. After the directory change, the directory listing command executes, sending the data back to the files opened in the original directory.
Where would the message from the last die go? Why, it would go into ls.err since that's where STDERR is going at that point. The die from chdir would go there, too. But where would the message go if we can't re-open STDERR on the second line? It goes to the old STDERR. For the three standard filehandles, STDIN, STDOUT, and STDERR, if re-opening them fails, the old filehandle is still open.