mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Swift: add possibility to run the extractor under an env-specified tool
if `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER` env variable is set, and either * `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER_FILTER` is not set, or * it is set to a regexp matching any substring of the extractor call then the extractor process is substituted with the command (and possibly options) stated in `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER`, followed by the system arguments of the extractor itself (which should include the extractor program itself at the start). Before calling `exec`, `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER` is unset to avoid unpleasant loops. An example usage is to run the extractor under `gdbserver :1234` when the arguments match a given source file.
This commit is contained in:
@@ -24,7 +24,9 @@ Notice you can run `bazel run :create-extractor-pack` if you already are in the
|
||||
|
||||
Using `codeql ... --search-path=swift/extractor-pack` will then pick up the Swift extractor. You can also use
|
||||
`--search-path=.`, as the extractor pack is mentioned in the root `codeql-workspace.yml`. Alternatively, you can
|
||||
set up the search path in [the per-user CodeQL configuration file](https://codeql.github.com/docs/codeql-cli/specifying-command-options-in-a-codeql-configuration-file/#using-a-codeql-configuration-file).
|
||||
set up the search path
|
||||
in [the per-user CodeQL configuration file](https://codeql.github.com/docs/codeql-cli/specifying-command-options-in-a-codeql-configuration-file/#using-a-codeql-configuration-file)
|
||||
.
|
||||
|
||||
## Code generation
|
||||
|
||||
@@ -53,3 +55,26 @@ options. This is known to have issues on non-Linux platforms.
|
||||
The `CMakeLists.txt` file allows to load the Swift extractor as a CMake project, which allows integration into a wider
|
||||
variety of IDEs. Building with CMake also creates a `compile_commands.json` compilation database that can be picked up
|
||||
by even more IDEs. In particular, opening the `swift` directory in VSCode should work.
|
||||
|
||||
### Debugging codeql database creation
|
||||
|
||||
If you want to debug a specific run of the extractor within an integration test or a complex `codeql database create`
|
||||
invocation, you can do so using [`gdbserver`][gdbserver] or [`lldb-server`][lldb-server].
|
||||
|
||||
[gdbserver]: https://sourceware.org/gdb/onlinedocs/gdb/gdbserver-man.html
|
||||
|
||||
[lldb-server]: https://lldb.llvm.org/man/lldb-server.html
|
||||
|
||||
For example with `gdbserver`, you can
|
||||
|
||||
```bash
|
||||
export CODEQL_EXTRACTOR_SWIFT_RUN_UNDER="gdbserver :1234"
|
||||
export CODEQL_EXTRACTOR_SWIFT_RUN_UNDER_FILTER="SomeSwiftSource\.swift" # can be any regex matching extractor args
|
||||
```
|
||||
|
||||
before starting the database extraction, and when that source is encountered the extractor will be run under
|
||||
a `gdbserver` instance listening on port 1234. You can then attach to the running debugging server from `gdb` or your
|
||||
IDE. Please refer to your IDE's instructions for how to set up remote debugging.
|
||||
|
||||
*Note for CLion users*: there is an issue for which breakpoints will not work in this mode if you are opening the
|
||||
workspace using the Intellij Bazel plugin. For the time being the workaround is to use the CMake project instead.
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <swift/Basic/LLVMInitialize.h>
|
||||
#include <swift/FrontendTool/FrontendTool.h>
|
||||
@@ -51,7 +53,51 @@ static void lockOutputSwiftModuleTraps(const codeql::SwiftExtractorConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
// if `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER` env variable is set, and either
|
||||
// * `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER_FILTER` is not set, or
|
||||
// * it is set to a regexp matching any substring of the extractor call
|
||||
// then the running process is substituted with the command (and possibly
|
||||
// options) stated in `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER`, followed by `argv`.
|
||||
// Before calling `exec`, `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER` is unset to avoid
|
||||
// unpleasant loops.
|
||||
// An example usage is to run the extractor under `gdbserver :1234` when the
|
||||
// arguments match a given source file.
|
||||
void checkToRunUnderTool(int argc, char* const* argv) {
|
||||
auto runUnder = getenv("CODEQL_EXTRACTOR_SWIFT_RUN_UNDER");
|
||||
if (runUnder == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto runUnderFilter = getenv("CODEQL_EXTRACTOR_SWIFT_RUN_UNDER_FILTER");
|
||||
if (runUnderFilter != nullptr) {
|
||||
assert(argc > 0);
|
||||
std::string call = argv[0];
|
||||
for (auto i = 0; i < argc; ++i) {
|
||||
call += ' ';
|
||||
call += argv[i];
|
||||
}
|
||||
std::regex filter{runUnderFilter, std::regex_constants::basic | std::regex_constants::nosubs};
|
||||
if (!std::regex_search(call, filter)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::vector<char*> args;
|
||||
for (auto word = std::strtok(runUnder, " "); word != nullptr; word = std::strtok(nullptr, " ")) {
|
||||
args.push_back(word);
|
||||
}
|
||||
if (args.empty()) {
|
||||
return;
|
||||
}
|
||||
for (auto i = 0; i < argc; ++i) {
|
||||
args.push_back(argv[i]);
|
||||
}
|
||||
args.push_back(nullptr);
|
||||
unsetenv("CODEQL_EXTRACTOR_SWIFT_RUN_UNDER");
|
||||
execvp(args[0], args.data());
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
checkToRunUnderTool(argc, argv);
|
||||
|
||||
if (argc == 1) {
|
||||
// TODO: print usage
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user