Skip to content
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

allow TASK_RUNNING and other #defines #153

Closed
brendangregg opened this issue Oct 9, 2018 · 4 comments · Fixed by #540
Closed

allow TASK_RUNNING and other #defines #153

brendangregg opened this issue Oct 9, 2018 · 4 comments · Fixed by #540
Labels
help wanted Extra attention is needed
Milestone

Comments

@brendangregg
Copy link
Contributor

sched.bt:

#include <linux/sched.h>

kprobe:do_nanosleep
{
	printf("%d\n", TASK_RUNNING);
}
# bpftrace sched.bt 
5.29: syntax error, unexpected ), expecting (

Looks like it's treating TASK_RUNNING as a bpftrace call, and so is expecting it to be followed by a '('.

I can workaround it by just including the TASK_RUNNING value (0x0) for now.

@mmarchini mmarchini added this to the 1.0 milestone Jan 14, 2019
@mmarchini mmarchini added the help wanted Extra attention is needed label Jan 14, 2019
@brendangregg
Copy link
Contributor Author

keep running into this

@gslavin gslavin mentioned this issue Apr 10, 2019
@mmarchini
Copy link
Contributor

Playing with libclang I was able to get the #define names, but not their expanded values :/

diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp
index b1db8ff..f0a1f6e 100644
--- a/src/clang_parser.cpp
+++ b/src/clang_parser.cpp
@@ -245,7 +245,7 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
       "definitions.h",
       &args[0], args.size(),
       unsaved_files, sizeof(unsaved_files)/sizeof(CXUnsavedFile),
-      CXTranslationUnit_None,
+      CXTranslationUnit_DetailedPreprocessingRecord,
       &translation_unit);
   if (error)
   {
@@ -261,6 +261,11 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
       {
         auto &structs = *static_cast<StructMap*>(client_data);
 
+        if (clang_getCursorKind(c) == CXCursor_MacroDefinition)
+        {
+          std::cout << get_clang_string(clang_getCursorSpelling(c)) << std::endl;
+        }
+
         if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
             clang_getCursorKind(parent) != CXCursor_UnionDecl)
           return CXChildVisit_Recurse;

I found others on the internet asking how to do this (here and here), but the workarounds are very hacky.

@mmarchini
Copy link
Contributor

From what I'm reading, the Preprocessor information might be accessible through clang's C++ API.

@mmarchini
Copy link
Contributor

Ok, I have a possible implementation based on this code. Basically I implemented a "preprocessor" in bpftrace: first we run our Bison parser stage to collect preprocessor stuff, structs, enums, etc., then we run our clang parser stage, and then we run our parser stage again, replacing all occurrences of macros with their literal values. This will work for multi-level macro definitions, because Bison will keep parsing and replacing until there's no macro left in its cursor. The downside (maybe it is not a downside) is that macros defining things that bpftrace can't parse will throw.

Will be opening a draft PR to discuss this further soon.

mmarchini added a commit to mmarchini/bpftrace that referenced this issue Apr 12, 2019
Add macro definition support as a bpftrace "preprocessor"-like feature.
This is implemented by running our Bison parser stage to collect
preprocessor stuff, structs, enums, etc., then we run our clang parser
stage, and then we run our parser stage again, replacing all occurrences
of macros with their literal values. This will work for multi-level
macro definitions, because Bison will keep parsing and replacing until
there's no macro left in its cursor. Macro expressions (`#define
MACRO()`) are not supported, but we can consider adding support for
those in the future. The downside (maybe it is not a downside) is that
macros defining things that bpftrace can't parse will throw.

Fixes: bpftrace#153
mmarchini added a commit that referenced this issue Apr 13, 2019
Add macro definition support as a bpftrace "preprocessor"-like feature.
This is implemented by running our Bison parser stage to collect
preprocessor stuff, structs, enums, etc., then we run our clang parser
stage, and then we run our parser stage again, replacing all occurrences
of macros with their literal values. This will work for multi-level
macro definitions, because Bison will keep parsing and replacing until
there's no macro left in its cursor. Macro expressions (`#define
MACRO()`) are not supported, but we can consider adding support for
those in the future. The downside (maybe it is not a downside) is that
macros defining things that bpftrace can't parse will throw.

Fixes: #153
mmarchini added a commit that referenced this issue Apr 15, 2019
Add macro definition support as a bpftrace "preprocessor"-like feature.
This is implemented by running our Bison parser stage to collect
preprocessor stuff, structs, enums, etc., then we run our clang parser
stage, and then we run our parser stage again, replacing all occurrences
of macros with their literal values. This will work for multi-level
macro definitions, because Bison will keep parsing and replacing until
there's no macro left in its cursor. Macro expressions (`#define
MACRO()`) are not supported, but we can consider adding support for
those in the future. The downside (maybe it is not a downside) is that
macros defining things that bpftrace can't parse will throw.

Fixes: #153
caringi pushed a commit to caringi/bpftrace that referenced this issue May 15, 2019
Add macro definition support as a bpftrace "preprocessor"-like feature.
This is implemented by running our Bison parser stage to collect
preprocessor stuff, structs, enums, etc., then we run our clang parser
stage, and then we run our parser stage again, replacing all occurrences
of macros with their literal values. This will work for multi-level
macro definitions, because Bison will keep parsing and replacing until
there's no macro left in its cursor. Macro expressions (`#define
MACRO()`) are not supported, but we can consider adding support for
those in the future. The downside (maybe it is not a downside) is that
macros defining things that bpftrace can't parse will throw.

Fixes: bpftrace#153
@mmarchini mmarchini modified the milestones: 1.0, 0.9.1 Jun 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants