filenames in a cross-platform environment

Hi all,

The question of how to tackle filename/path issues in a cross-platform
environment arose as a result of http://reviews.llvm.org/D12115, and we would
like to continue that discussion here. I'll start with excerpts from comments
in that review to give you some background:

zturner:
    [...] can we instead use llvm::sys::fs::root_name to check whether the path
    contains a drive letter?

dawn:
    Sadly no, because root_name only parses c:\ correctly if the platform is
    Windows. Our IDE is hosted on Windows but talks to lldb running on OSX. I've
    had this path problem with the DWARF reader and FileSpec - lldb has a core
    assumption that you only want to support Windows paths if you run on Windows.
    At least with FileSpec you can pass a PathSyntax, but you have to choose either
    Windows or Posix, not both. We want to support both Posix and Windows style
    paths. I've not come up with a clean patch for this problem so none have been
    submitted.

zturner:
    Are you saying that there is a situation where you are given a path, and you
    have no idea whether it is a posix path or a windows path?

dawn:
    Yes. For example, in lldb on OSX, we can be debugging an app that was built on
    OSX, or an app that was built on Windows targeting OSX. More likely, we would
    be debugging an app that was built on Windows but links with libraries that
    were built on OSX.

    I've thought of various ways to fit this into lldb... One idea was to add:
        settings set target.pathsyntax [posix|windows|any|native] #default=native
    and a FileSpec::ePathSyntaxAny enum which would be set if the user chose "any".
    But that doesn't solve the problem for llvm, whose path handling appears to be
    controlled by the define LLVM_ON_WIN32.

Thoughts/ideas?

Thanks in advance,
-Dawn

Hi all,

The question of how to tackle filename/path issues in a cross-platform
environment arose as a result of http://reviews.llvm.org/D12115, and we would
like to continue that discussion here. I'll start with excerpts from comments
in that review to give you some background:

[snip]

Thoughts/ideas?

I solved this quite a few years ago inside of “GDB-TK/Insight” - my situation was:

  Some libraries are built on: Linux + SunOS + Cygwin + MSDOS + MAC (prior to Unix-fication, colons in the path)
  Libraries and Apps could be built on any of those. Hence we had many different combiations.

Today - you are talking about LLDB - which potentially has python under the hood.
In my case GDB-TK/Insight - it was Tcl/Tk built in.

My solution worked like this:

When GDB failed to find the filename by “the normal means” - I made GDBTK call a TCL/TK function

If that function did not exist - the code just gave up - too bad you do not get to find the file.
This was the default action if you (the user) did not provide a lookup function.

If that function existed - in my case, we wrote one or two functions for each project
And, when you launched GDB we just did a “source project_paths.tcl” in the .gdbinit script

The beauty is this:
  You will never get all of these features and corner cases resolved.
  The solution is very adaptable, and the user can do what is required.
  The user can - if they desire - write a fix-up function

The default implementation would be this simple - it does nothing.

def my_find_my_file( filename ):
  # Default implementation .. just return the filename
  return filename

You could, get really fancy -
  You could go lookup the file name via a GIT-WEB service and pull it locally.
  Thus you do not need 100% of the source code present it comes in on demand.
  But that is a *USER* solution - all you are doing is calling a function they can write.

Example:

def my_find_my_file(filename):
  if filename.startswith( ‘/proj/libfoo/rev1.0’ ):
    return git_web_lookup( foo_server, filename );
  else:
    return filename

NOTE: Please … I beg you:
  Do not pass the base-name, pass the entire path from the debug record.
  Why? Because often you find duplicate filenames the full path is better!

Even better:
  Pass the symbol name, the address, and line number the function.
  And - the DW_LNF_MD5 (md5 sum of the source file?)
  And … the list goes on and on

In the LLDB case, that function could be written by the user in Python
or perhaps example python template can be provided with some simple instructions.

-Duane.

Today - you are talking about LLDB - which potentially has python under the hood.

This can't be in python - the main LLDB code needs to support it.
* LLVM supports it using a preprocessor define, which obviously won't work because
it is compiled in. LLVM will have to be made to check flags at runtime.
* LLDB can be fixed to support both via it's PathSyntax functionality, but
the question is how to do this cleanly. I proposed adding an option.

My solution worked like this:

When GDB failed to find the filename by ???the normal means??? - I made GDBTK call a TCL/TK function

If that function did not exist - the code just gave up - too bad you do not get to find the file.
This was the default action if you (the user) did not provide a lookup function.

If that function existed - in my case, we wrote one or two functions for each project
And, when you launched GDB we just did a ???source project_paths.tcl??? in the .gdbinit script

Yeah, that was the gdb way of supporting alternate functionality
(to check if a function was defined and call it) - it worked pretty
well. It doesn't really fit in well with LLDB design however. LLDB's
way of supporting alternate functionalities is through plugins or
options. In this case an option seems most reasonable.

Thanks,
-Dawn