This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: How can I access ULONG_MAX constant without using -g option?
- From: Tetsuo Handa <penguin-kernel at I-love dot SAKURA dot ne dot jp>
- To: fche at redhat dot com
- Cc: systemtap at sourceware dot org
- Date: Wed, 7 May 2014 23:13:23 +0900
- Subject: Re: How can I access ULONG_MAX constant without using -g option?
- Authentication-results: sourceware.org; auth=none
- References: <201405061502 dot JDC34371 dot FFVOSFQtOOHMJL at I-love dot SAKURA dot ne dot jp> <y0moazaisop dot fsf at fche dot csb>
Frank Ch. Eigler wrote:
> > [...]
> > # stap -e 'probe begin { printf("current=%lx\n", task_current()); exit(); }'
> > current=ffffffffc1681aa0
> > In the example output above, current=c1681aa0 is the expected value on i686.
>
> To an extent, this is expected from use of signed pointer types. They
> are sign-extended when widened. Is there some operational impact from
> the upper 32-bits being set in your script, or just an aesthetic
> preference?
I'm using address of "struct task_struct" as element of associated array
in order to emulate per a "struct task_struct" variable which is copied
upon fork() and updated upon execve() and deleted upon exit().
---------- my script start ----------
# stap -g -DMAXSTRINGLEN=4096 -e '
global task_domain[32768];
function get_current:long() {
return task_current() & %{ ULONG_MAX %};
}
function is_success:long(ret:long) {
return ret <= -4096 || ret >= 0;
}
function make_domain:string() {
task = get_current();
if (task_domain[task] == "")
task_domain[task] = sprintf("%s(%d)", execname(), pid());
return task_domain[task];
}
probe kernel.function("copy_process").return {
if (is_success($return))
task_domain[$return] = make_domain();
}
probe kernel.function("do_execve") {
make_domain();
}
probe kernel.function("do_execve").return {
if (is_success($return)) {
task = get_current();
domain = task_domain[task];
if (domain != "") {
filename = kernel_string($filename);
printf("[%s] starting %s by uid=%d from %s\n", ctime(gettimeofday_s()),
filename, uid(), domain);
task_domain[task] .= " " . filename;
}
}
}
probe kernel.function("free_task") {
delete task_domain[$tsk];
}
probe end {
delete task_domain;
}'
---------- my script end ----------
While copy_process() returns 32-bits address and free_task() receives 32-bits
address, task_current() returns 64-bits address. As a result, I must use only
lower 32-bits of 64-bits address in order to access appropriate element of
associated array.
Also, it sounds inconsistent to me that
function task_current:long ()
function task_parent:long(task:long)
function pid2task:long (pid:long)
which returns address of "struct task_struct" as "long" returns addresses of
different width.
# stap -e 'probe begin { task = task_current();
printf("current=%lx\nparent=%lx\ninit=%lx\n", task, task_parent(task),
pid2task(1)); exit(); } '
current=fffffffff5c7b550
parent=c1581000
init=fffffffff7081aa0
I think that returning 32-bits address on 32-bits kernel like
current=f5c7b550
parent=c1581000
init=f7081aa0
is the expected result which can be done by making changes shown below.
--- task.stp
+++ task.stp
@@ -29,7 +29,7 @@
* more task-specific data.
*/
function task_current:long () %{ /* pure */
- STAP_RETVALUE = (long)current;
+ STAP_RETVALUE = (unsigned long)current;
%}
/**
@@ -110,7 +110,7 @@ function pid2task:long (pid:long) %{ /*
#endif /* 2.6.24 */
#endif /* 2.6.31 */
rcu_read_unlock();
- STAP_RETVALUE = (long)t;
+ STAP_RETVALUE = (unsigned long)t;
%}
/**