fkho@watdragon.waterloo.edu (Frederick K. Ho) (04/23/91)
Hi, I would like to know if anyone tried to register a signal inside a
member function with the callback signal handler being another member
function of the same class?
I have experiencing trouble inside the wakeup routine where I got BUS
error (alignment error). The this pointer seems to be corrupted.
Here's what I did:
class A
{
private:
int to;
public:
A();
~A();
f();
timeout();
};
A::timeout()
{
to = 1;
}
A::f()
{
// register the signal
::signal(SIGALRM, timeout);
...
}
Has I done anything wrong?
//fred
U. of Waterloo
--
Internet: fkho@watdragon.waterloo.{edu|ca}
UUCP: {ihnp4,decvax,uunet,utai, ...}!watmath!watdragon!fkho
Bitnet: fkho@water.BITNET, fkho@water.uwaterloo.casteve@taumet.com (Stephen Clamage) (04/23/91)
fkho@watdragon.waterloo.edu (Frederick K. Ho) writes: >Hi, I would like to know if anyone tried to register a signal inside a >member function with the callback signal handler being another member >function of the same class? I don't believe you can do this. The member function must be called with a 'this' pointer, which the operating system will not be able to supply. >class A { > ... > f(); > timeout(); >}; >A::f() >{ > ::signal(SIGALRM, timeout); > ... >} The second paramater to signal() is of type "pointer to function taking one int parameter, returning void". The type of "timeout" is "pointer to member function of A with no parameters, returning int". This is a type mismatch, and you should have gotten a compile-time error at the call to signal(). It should be ok if timeout is a static member function of the right type: class A { ... static void timeout(int); ... }; -- Steve Clamage, TauMetric Corp, steve@taumet.com
fkho@watdragon.waterloo.edu (Frederick K. Ho) (04/25/91)
Hello, Here's the summary of responses I have received from the net regarding my question on using UNIX signal in C++. I thank all who responsed, I am grateful to you all. As suggested, I am now making my member function timeout() and variable "to" static in class A. Although it's not an elegant solution but it serves my purpose right now since I will not have more than one instantiation of the class A object. If anyone has a better solution, I would like to hear from you in how you do it. Thank you again. //fred U. of Waterloo In article <1991Apr22.194302.17795@watdragon.waterloo.edu> you write: |> Here's what I did: |> |> class A |> { |> private: |> int to; |> public: |> A(); |> ~A(); |> f(); |> timeout(); |> }; |> |> A::timeout() |> { |> to = 1; |> } |> |> A::f() |> { |> // register the signal |> ::signal(SIGALRM, timeout); |> |> ... |> } |> |> |> Has I done anything wrong? |> From pat%bnrmtl.UUCP@Larry.McRCIM.McGill.EDU Mon Apr 22 17:02:46 1991 Yes. With a good set of system header files, this should not even compile. If I remember correctly, the second parameter to signal() is a function taking an int argument (the signal number) and returning nothing. Something like this: typedef void handler( int ); extern handler signal( int, handler ); (Caveats: I may have remembered this incorrectly, and it may be different on your system. Anyway, the gist is surely correct.) You, however, are passing a member function as the second argument to signal(). This is a beast of an entirely different colour, and it just won't work (For starters, how would your timeout() know which object it should modify?). One solution would be to make to and timeout static members (one instance of each, rather than one per object). Something like: class A { ... static int to; static void timeout( int ); }; A::timeout( int ) { to = 1; } Static members (both data and functions) behave just like normal data objects and functions declared outside of classes, except for the the scoping rules and such like, so this should work. -- Patrick Smith Bell-Northern Research, Montreal, Canada (514) 765-7914 bnrmtl!pat@larry.mcrcim.mcgill.edu patrick@bnr.ca These are my opinions, not facts; BNR may or may not agree with them. =================================== From peter@csg.uwaterloo.ca Mon Apr 22 19:18:50 1991 In article <1991Apr22.194302.17795@watdragon.waterloo.edu> you write: I'm pretty sure you can't pass the address of a member function to signal. The documentation for signal should tell you. Peter =================================== From ken@csis.dit.csiro.au Tue Apr 23 03:02:24 1991 Since signal handlers must be non-member functions, how would you make sure a member function is called with the correct "this"? One way out is to have a non-member function in between. =================================== From torda@igc.ethz.ch Tue Apr 23 03:03:14 1991 You don't say what machine or compiler, but have you tried ::signal (SIGALRM, A::timeout) ? I had some more luck giving a more qualified name. Didn't understand it, but it helped on a sparc with OS 4.1 and SunC++. Good luck. -- Andrew Torda, ETH, Zurich =================================== From olseno@cs.glasgow.ac.uk Tue Apr 23 11:51:54 1991 All member functions, unless they are static, expects the first argument to be a pointer ('this') to the variables of the class, in your case 'to'. This argument is implicitly included and one normally does not need to know it exists. I.e. A::timeout() looks like A::timeout( A * this ) { this->to = 1; } and in main() { A a; a.timeout(); } is compiled as timeout( &a ); In your case, on the signal, execution is transferred to A::timeout(), but the argument this is not supplied, and hence this points to an arbitrary location and you get a bus error. ----------------------------------------------------- Oystein Haug Olsen, Dept. of Electronics Engineering, Univ. of Glasgow, Glasgow G12 8QQ, U.K. JANET: olseno@uk.ac.glasgow.cs USENET: olseno@cs.glasgow.uucp BITNET: olseno%dcs.glasgow@UKACRL ARPA: olseno%glasgow.dcs@nsfnet-relay.ac.uk =================================== From @yonge.csri.toronto.edu:tom@scocan Tue Apr 23 16:11:03 1991 You've done something wrong. When the operating system invokes the signal handler, it does not set up a "this" pointer, the first argument is the signal (int sig). You cannot directly register member functions with the signal routine, you have to put a wrapper around it. Tom Kelly (416) 922-1937 SCO Canada, Inc. (formerly HCR) 130 Bloor St. W., Toronto, Ontario, Canada {utzoo, utcsri, uunet}!scocan!tom or tom@sco.com =================================== From ahodgson@hstbme.mit.edu Tue Apr 23 16:54:31 1991 I think the problem is that ::signal never gets the "this" pointer and therefore can't call timeout properly (all member functions ALWAYS need to be called in the context of an existing object). One possible approach is to use static member functions and variables: class A { static to; static timeout() { to = 1; } ... } ::signal( ALARM, A::timeout ); A::timeout is well-defined and can be called even if no objects of type A exist. If you intend the message to be received by a particular object of type A, you must define another static variable as a pointer to an object of type A and send the appropriate message to it in timeout. Hope this helps. Tony Hodgson ahodgson@hstbme.mit.edu ============================================ From cline@cheetah.ece.clarkson.edu Wed Apr 24 02:02:41 1991 The address of `timeout()' is a pointer-to-member-fn, not a ptr-to-fn. The difference is easy to see by asking this question: which A *object* should be the receipient of the `timeout()' message from signal()? Since ::signal() requires a ptr-to-fn, you must create a top-level (file- scope) fn that calls `timeout()' on the proper A object. Marshall Cline Keeper of the Borland C++ Bug Report PS: If your company is interested in on-site C++/OOD training, drop me a line! -- Marshall Cline / Asst.Prof / ECE Dept / Clarkson Univ / Potsdam, NY 13676 cline@sun.soe.clarkson.edu / Bitnet:BH0W@CLUTX / uunet!clutx.clarkson.edu!bh0w Voice: 315-268-3868 / Secretary: 315-268-6511 / FAX: 315-268-7600 ============================================ From vaughan%cadillac.cad.mcc.com@mcc.com Wed Apr 24 14:25:28 1991 You would have to use a static member function or a non-member function. You noticed that the this pointer is corrupt, but think about it--where is the this pointer coming from? (answer, nowhere) -- Internet: fkho@watdragon.waterloo.{edu|ca} UUCP: {ihnp4,decvax,uunet,utai, ...}!watmath!watdragon!fkho Bitnet: fkho@water.BITNET, fkho@water.uwaterloo.ca