Hi team I had a function trace demo with Struct parameter and Struct return, but got the "cannot handle offset into register" error. my environments: os: Ubuntu 16.04 LTS gcc 8.3 systemtap 4.5 elfutils 0.185 # func.h struct DataPackage { int len; float width; // float width2; // uncomment this line will work :) double angle; }; struct DataPackage func_complex_v2(struct DataPackage input_data, int page); # func.c struct DataPackage func_complex_v2(struct DataPackage input_data, int page) { struct DataPackage d; d.len = 19; d.width = 115.33; d.angle = 6.66; return d; } # main.c int main(int argc, char const *argv[]) { struct DataPackage d; d.len = 997; d.width = 10; d.angle = 0.777; struct DataPackage r =func_complex_v2(d, 789); return 0; } # cc_stap_test_complex.stp probe process("/home/xyz/vs_workspace/CacheLab/build/test").function("func_complex_v2").return { printf("func_complex_v2 return: %s\n", fp_to_string($return->width, 6)) } Here is the console output: Debug translate_offsetsemantic error: cannot handle offset into register: identifier '$return' at /home/xyz/cc_stap_test_complex.stp:73:57 source: printf("func_complex_v2 return: %s\n", fp_to_string($return->width, 6)) ^ semantic error: unresolved type : identifier '$return' at :73:57 source: printf("func_complex_v2 return: %s\n", fp_to_string($return->width, 6)) Any advice is appreciate, thanks!
This is due to the x8664 abi which specifies how structures are passed. The structure in the example is returned by value, which will return the struct members in successive registers as specified by the x8664 abi. In this particular case members are packed into a single register and systemtap is thus not able to pry it apart. Thus the error "cannot handle offset into register" The abi says: The classification of aggregate (structures and arrays) and union types works as follows: 1. If the size of an object is larger than four eightbytes, or it contains unaligned fields, it has class MEMORY So if the example is changed to be double width; double angle; then the abi threshold is hit, the struct is passed by reference and systemtap can then access individual members.
> In this particular case members are packed into a single register and systemtap is thus not able to pry it apart. Thus the error "cannot handle offset into register" Why can systemtap not handle this though? I believe the code knows about larger values being split across memory words or registers.
It is hitting this case: dwflpp::translate_base_ref case loc_register: if (loc->offset != 0) throw SEMANTIC_ERROR (_("cannot handle offset into register"), ctx.e->tok); // The existing program is the value. break;
Been working on PR29037. For bitfields there is some logic that handles to extract the bitfield of interest. It doesn't look like there is similar code to extract other members of a struct: https://sourceware.org/git/?p=systemtap.git;a=blob;f=dwflpp.cxx;h=ae06933df865fe1c6070327e72d103a14b0039d0;hb=refs/heads/master#l4000