This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How can I access ULONG_MAX constant without using -g option?


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;
 %}

 /**


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]