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

segmentation fault: in callback function when using actionlib #251

Open
wkentaro opened this issue Feb 21, 2015 · 18 comments
Open

segmentation fault: in callback function when using actionlib #251

wkentaro opened this issue Feb 21, 2015 · 18 comments

Comments

@wkentaro
Copy link
Member

When using actionlib and roseus, I had segmentation fault in its callback function, and resolved it by passing arguments to callback function.

I mean, in the sample code:
https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/test/fibonacci-server.l

from

(setq s (instance ros::simple-action-server :init
                  "/fibonacci" actionlib_tutorials::FibonacciAction
                  :execute-cb #'fibonacci-execute-cb))

to

(setq  s (instance ros::simple-action-server :init
                  "/fibonacci" actionlib_tutorials::FibonacciAction
                  :execute-cb #'(lambda (server goal) (fibonacci-execute-cb server goal)))

This segmentation fault doesn't always happen, and the sample code has no problem. In my project, however, I had it.

Actually I don't know the fundamental cause but in my case it is resolved with upper change. As reference my change log is:
wkentaro/jsk_apc@ac8dddf#diff-2a23e2389483ccb4c96d7f07ba40062eR58

@garaemon
Copy link
Member

To put it simply, you cannot use #'(lambda (...) ...) form in instance because euslisp does not support closure (Technically, you can use deligation pattern for this problem).

In order to understand this issue perfectly, you need to know closure, free variables, let frame, macro expansion. It's a good lesson to understand how software works.

@wkentaro
Copy link
Member Author

Thanks to your introduction, I read some documents of these. I think I understood your point.
Does the code #('lambda (...) ...) problem, if I don't intend to use free variables outside (lambda (...) ...) scope?

In the actionlib.l,
https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/euslisp/actionlib.l#L233
it uses (funcall exeucte-cb self goal) so :execute-cb #'execute-cb in instance should be okay. However, in my case it raises segmentation fault.
×:execute-cb #'execute-cb
:execute-cb execute-cb:execute-cb #'(lambda (server goal) (execute-cb server goal):execute-cb (lambda (server goal) (execute-cb server goal))

@garaemon
Copy link
Member

Does the code #('lambda (...) ...) problem, if I don't intend to use free variables outside (lambda (...) ...) scope?

It' a deep world of euslisp.

  • euslisp SHOULD be able to call lambda form without free variables.
  • euslisp CANNOT call lambda form which can have free variables outside of its parent environment.

It means that euslisp cannot call lambda function which is created in another let form.

On the other hand, euslip can funcall symbol and in that case euslip evaluate the symbol as function when calling funcall (it's a not common lisp standard).
https://github.com/euslisp/EusLisp/blob/master/lisp/c/eval.c#L1072

(funcall #'+ 1 2)
; => 3

(funcall '+ 1 2) 
; => 3

And, euslisp can call closure even if the environment pointed by closure is on stack.

(let ((var 1))
  (let ((f #'(lambda (x) var)))    ; closure include free variable!
    (print (funcall f 100)))) ; call inside of environment 
; => 1
(funcall (let ((var 1)) ; call out side of environment
           (let ((f #'(lambda (x) var)))    ; closure!
             f)) 1)
; => SEGV

@garaemon
Copy link
Member

(funcall (let ((var 1))
           (let ((lambda '(lambda (x) var)))    ; closure!
             lambda)) 1)
; => undefined variable var!

Because the code is evaluated as

(funcall (eval '(lambda (x) var)) 1)

And when euslisp evaluate the lambda, there is no such variable like var

@garaemon
Copy link
Member

And let us assume the code like followings:

(let ((a 1)) ;; let-a
  (let ((b 2)) ;; let-b
     (let ((c 3)) ;; let-c
   )))

Stack of environment in euslisp evaluator is:

nest depth nickname parent environment
0 global scope none
1 let-a global
2 let-b let-a
3 let-c let-b

Euslisp can call lambda which created in parent environment.

defun always create lambda in global scope so that you can call defun-ed functions in any let scopes.

However if you have lambda craeted in let-b, you can call it in let-b and let-c scope but you cannot call it in let-a and global scope

@garaemon
Copy link
Member

This article may help you to understand stack VM.

@wkentaro
Copy link
Member Author

Thanks. I got to know some of the characteristics of euslisp and what I should keep in mind when using it.

@k-okada
Copy link
Member

k-okada commented Mar 13, 2015

sorry for super late response, but did you said that
https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/test/fibonacci-server.l
does not working? and we need to rewrite as :execute-cb #'(lambda (server goal) (fibonacci-execute-cb server goal) ??

◉ Kei Okada

On Fri, Feb 27, 2015 at 5:44 PM, Kentaro Wada notifications@github.com
wrote:

Thanks. I got to know some of the characteristics of euslisp and what I
should keep in mind when using it.


Reply to this email directly or view it on GitHub
#251 (comment)
.

@wkentaro
Copy link
Member Author

No, fibonacci-server.l has no problem.
But in my code I had to write as :execute-cb #'(lambda (server goal) (fibonacci-execute-cb server goal).

@k-okada
Copy link
Member

k-okada commented Mar 14, 2015

may be you can write as :execute-cb #'send self :execute-cb,
https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/test/listener.l#L28

◉ Kei Okada

On Sat, Mar 14, 2015 at 1:15 PM, Kentaro Wada notifications@github.com
wrote:

No, fibonacci-server.l has no problem.
But in my code I had to write as :execute-cb #'(lambda (server
goal) (fibonacci-execute-cb server goal).


Reply to this email directly or view it on GitHub
#251 (comment)
.

@wkentaro
Copy link
Member Author

In this code, :execute-cb #'execute-cb raises unexpected error.
(this is why I opened this issue)
wkentaro/jsk_apc@ac8dddf#diff-2a23e2389483ccb4c96d7f07ba40062eR58

and
In this code
:execute-cb #'send self :execute-cb also raise other error message.
It seems that in instance block of ros::simple-action-server we can't use :execute-cb #'send self :execute-cb.
wkentaro/jsk_apc@c583794#diff-92fac444fd3df4007e9776ba5f97ac76R29

@garaemon
Copy link
Member

self is problem, self cannot be resolved in global scope. the callback is just evaled by eval special form on the top level scope

@k-okada
Copy link
Member

k-okada commented Jun 15, 2015

I see, please describe that on
https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/roseus.cpp#L1555
so that we can see that note on
http://euslisp-docs.readthedocs.org/en/latest/roseus/roseus/#rossubscribe >
@wkentaro

◉ Kei Okada

On Fri, Jun 12, 2015 at 3:32 PM, Ryohei Ueda notifications@github.com
wrote:

self is problem, self cannot be resolved in global scope. the callback is
just evaled by eval special form on the top level scope


Reply to this email directly or view it on GitHub
#251 (comment)
.

@wkentaro
Copy link
Member Author

I have never encountered this problem when using subscriber but actionlib.
Is that really impossible to use self in callback function of subscriber, and this is problem?
In that case, I have no idea how to declare subscription using an instance method as callback function.. :(

@garaemon
Copy link
Member

:execute-cb #'send self ...
This syntax is simply not supported. https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/euslisp/actionlib.l#L338

@garaemon
Copy link
Member

In subscription callback function, #'send self :foo is evaluated before ros::subscribe is called

@wkentaro
Copy link
Member Author

I see, please describe that on
https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/roseus.cpp#L1555
so that we can see that note on
http://euslisp-docs.readthedocs.org/en/latest/roseus/roseus/#rossubscribe >
@wkentaro

I see, so where should I describe about that? @k-okada
It seems that https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/roseus.cpp#L1555 has nothing to change.

@furushchev
Copy link
Member

@wkentaro Is this issue solved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants