-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sourced files can't be always resolved #63
Comments
I don't understand. The POSIX shell debuggers like bashdb call bashdb's callback hook ( Given this, the code in You might be able to come up with some sneaky kind of program where sourcing the same relative path name appears more than once and refers to different places due to a change in cwd: cd /tmp
source foo.sh
cd /home/joe
source foo.sh # different foo.sh from above
# here we've already associated foo.sh with /tmp/foo.sh and that might take precedence over /home/joe/foo.sh For this, one would need more elaborate mechanisms. But until we run into this case, I am happy to postpone working on it. |
@rocky Thanks! I'll try to clarify what I meant. As far as I understand: Here's a self-contained example: #!/usr/bin/env bash
mkdir -p "libs"
echo "myFunc() { echo \"myFunc(): PWD='\$PWD' BASH_SOURCE='\${BASH_SOURCE[0]}'\"; }" > "libs/include.sh"
mkdir -p "some/other/dir"
cd "some/other/dir"
set -o functrace
trap 'echo [DEBUG] $BASH_COMMAND PWD=$PWD BASH_SOURCE=${BASH_SOURCE[0]}' DEBUG
. "../../../libs/include.sh"
cd ../../..
myFunc If I run this with Bash 5.2, then it prints this:
The relevant line is The only solution I can think of is to record and resolve sourced paths in this trap handler call: It would be much better if Bash itself fixed this by always passing absolute paths in Of course, it's possible that I'm missing something. |
As you note, what is recorded in In this particular situation, sourcing "include.sh" does not have any callback events. In contrast to say Python where there is a stop before defining a function, in bash there is no stop before lines that define functions. If "include.sh" were instead: func() { echo \"myFunc(): PWD='\$PWD' BASH_SOURCE='\${BASH_SOURCE[0]}'\"; }
x=1 The debugger as written would pick up the association because there is a stop before
In POSIX shells, and bash in particular, parsing a command-line string is tricky because of the 2- or 3-phase substitution process. And these languages do not provide a "parse" function to parse into an AST as you find in Python and similar languages. In short, Parsing the command string cannot be done easily or reliably to determine if it is a "source" command and, if so, what the source file name is.
Yes, this is what I wrote in the third paragraph in #50 (comment) Python made this same mistake in recording path names but has fixed it recently. I think Ruby made the same mistake too but I think it also fixed this early on. And the motivation for this there was for the same reason as here. |
Thank you for your feedback. You‘re right, the correct solution is to fix this in Bash and you mentioned that before. I‘ll post on the Bash mailing list. |
Follow up to #50
I think that I have a better understanding now of what's going on.
For this script:
The trap handler invoked when
function_from_lib.bash
is executed, has this data:$BASH_SOURCE[1] == ../lib.bash
$PWD == $HOME
To manage breakpoints, we have to resolve
../lib.bash
to its source file.But atm we're only attempting to guess its directory by looking into directories
${_Dbg_init_cwd}
,$_Dbg_cdir
and$(pwd)
.But files can be sourced from any directory, based on the working directory at the time
source
is called.To reliably find the source file of
../lib.bash
we need to know the working directory whensource ../lib.bash
is called, i.e. we need to know that it's/path/to/some-dir
.With debug output added to the TRAP handler, this is what's available when
cd some-dir
and. ../lib.bash
is called:Possible approach: In the trap handler, it may work to detect
.
andsource
commands in$_Dbg_bash_command
and store the absolute path of../lib.bash
based on the current$PWD
. This would involve parsing the bash command and there won't be a complete solution handling all edge-cases. But managing the basicsource ./file/path ignored-args...
should be possible, I think.I'm not an expert with trap handlers and it's possible that I'm not aware of other, possible solutions.
@rocky Do you think that this may work? Do you perhaps know a better approach to solve this?
The text was updated successfully, but these errors were encountered: