Closed zacps closed 6 years ago
What do you mean by 'web servers'? The net/http package? This tool checks all the calls inside program. By default it focuses only main package. Check the options in README. Or show code you are trying to analyze.
I don't see an option to enable stepping into the stdlib, just the nostdlib option. Yes i was taking about net/http. This shows the call to listen and serve but not calls out to handlers.
I think I understand now. ~This is probably related to #4 where the issue was similar.~
Basically, only the calls from and to the focused package (main by default) are shown. That means that it will only display calls that are directly called from your focused package to the net/http and ones that are directly from net/http to your focused package. You could use empty string for the -focus
flag to show ALL the calls of the program. However this will generate huge output if you don't use -limit
or -ignore
.
EDIT: Actually I am not sure now... I could help more if you provided some code examples.
So the entry point is main.go which calls a function to setup the routes in another file (same package). After that it calls listen and serve. The routes call into another package called views which calls into another package and so on.
Does specifying a directory (recursively) work?
Could you show the command with the arguments you used to generate the output?
Since you provided no example code. I made small example to show that the calls from net/http to handlers are shown.
Code:
package main
import (
"fmt"
"net/http"
)
func main() {
setupRoutes()
http.ListenAndServe(":4321", nil)
}
func setupRoutes() {
http.HandleFunc("/", index)
}
func index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "index")
}
Command:
go-callvis playground/callvis | dot -Tpng -o callvis.png
Output:
That code works. However when I took the index method out of the main file and moved it into it's own directory it didn't. Even though I explicitly imported it:
go-callvis . ./api/ | dot -Tpng -o callvis.png
api/main.go
package api
import (
"fmt"
"net/http"
)
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "index")
}
main.go
package main
import (
"github.com/zacps/test/api"
"net/http"
)
func main() {
setupRoutes()
http.ListenAndServe(":4321", nil)
}
func setupRoutes() {
http.HandleFunc("/", api.Index)
}
Not sure what's going on here...
I've played around with different code structure and various flag options. I will try to summarize my findings.
Let's start with the command you used: go-callvis . ./api/ | ...
Maybe it doesn't throw error and probably should, but only one argument is supported currently (which has to be a main package). Other arguments after the first one are ignored, because important is the main package where the program starts, and the code analysis can figure out all other calls from there.
The -focus
flag is by default set to main
since all the programs
have it and keeping focus empty by default would generate gigantic output.
In my example I posted before, it's pretty straightforward since only single package is used.
either have both caller and callee function inside the focused package,
main.main()
--> main.setupRoutes()
or have only caller function inside the focused package,
main.main()
--> http.ListenAndServe()
main.setupRoutes()
--> http.HandleFunc()
main.index()
--> fmt.Fprintf()
or have only callee function inside the focused package.
http.(HandlerFunc).ServeHTTP()
- - > main.index()
If the program consists of multiple packages like in your case, you can choose another package for -focus
or use empty focus
with relevant -limit
and -ignore
flags to constraint the size of output.
main.go
package main
import (
"playground/callvis/api"
"net/http"
)
func main() {
api.SetupRoutes()
http.ListenAndServe(":4321", nil)
}
api/api.go
package api
import (
"fmt"
"net/http"
)
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "index")
}
func SetupRoutes() {
http.HandleFunc("/", Index)
}
main
Output doesn't show call to http.HandleFunc()
and fmt.Fprintf()
, because neither caller nor callee are inside focused package.
go-callvis -focus main -group pkg playground/callvis | ...
api
Output doesn't show call to http.ListenAndServe()
, because neither caller nor callee are inside focused package.
However it still shows api.SetupRoutes()
call since it is inside api
package.
go-callvis -focus api -group pkg playground/callvis | ...
By using -limit
we can define import path prefix and packages without this prefix will be ignored.
Same way the -ignore
flag defines import path for ignoring packages.
Both can contain multiple prefix paths.
go-callvis -focus="" -limit playground/callvis -group pkg playground/callvis | ...
net/http
We can add net/http
package to the -limit
to include it's callgraph. This generates huge output, because it contains internal calls inside std packages.
go-callvis -focus="" -limit "net/http,playground/callvis" -group pkg playground/callvis | ...
To me it seems there is missing a way to show output similar to the last one without the internal calls of the std package.
I think the behaviour of -nostd
should be changed so it only omits internal calls inside and between std packages. Or some new flag added with default true
since I assume that not many users are interested in internal calls inside std package.
I will look into this further to find the most optimal solution.
Is this because it doesn't check calls inside the stdlib?