digitalmars.D.learn - segfaults
- Ellery Newcomer (17/17) May 03 2010 Hello.
- Lars T. Kyllingstad (5/29) May 03 2010 It's a null dereference. What you're doing is essentially
- Bernard Helyer (3/32) May 03 2010 I believe his problem is that the return code of the caller indicates
- Steven Schveighoffer (6/42) May 03 2010 Could it be perhaps that it can't possibly get at that status? Remember...
- Bernard Helyer (2/11) May 03 2010 sh -c returns failure if the specified executable segfaults.
- Ellery Newcomer (2/6) May 03 2010 All I know is the analogous code in python returns the expected 139
- Graham Fawcett (18/27) May 03 2010 What OS are you running on? In D2, this the definition of system():
- Ellery Newcomer (6/22) May 03 2010 I'm on fedora, and yeah, I guess it's a posixism. investigation yields
- Lars T. Kyllingstad (16/32) May 03 2010 That hardcoded bit shift in std.process is really ugly, and hides what i...
- Ellery Newcomer (29/36) May 04 2010 That's good to hear. And since you're an expert in this stuff, does this...
- Graham Fawcett (5/54) May 04 2010 Thanks for posting this. Just curious -- why did you choose to model PID...
- Ellery Newcomer (6/10) May 04 2010 according to core.sys.posix.sys.wait, this is only valid for linux, grrr...
- Lars T. Kyllingstad (11/47) May 04 2010 Shouldn't 'term' and 'signaled' switch names? It looks to me like 'term...
- Ellery Newcomer (20/27) May 04 2010 signaled corresponds to WIFSIGNALED, whatever that is, and takes its nam...
- Lars T. Kyllingstad (8/45) May 05 2010 Don't know. Since all the other WIF* tests return bool, that looks like...
- Lars T. Kyllingstad (4/22) May 03 2010 Note to self: Read posts *thoroughly* before answering. Man, I was
Hello. I'm trying to invoke a command inside d, and it returns a success code when the command in question segfaults. any ideas? // the caller import std.process; int main(){ auto r = system("./test"); return(r); } //test.d import std.stdio; void main() { Object o; writeln(o.toString()); }
May 03 2010
On Mon, 03 May 2010 15:54:28 -0500, Ellery Newcomer wrote:Hello. I'm trying to invoke a command inside d, and it returns a success code when the command in question segfaults. any ideas? // the caller import std.process; int main(){ auto r = system("./test"); return(r); } //test.d import std.stdio; void main() { Object o; writeln(o.toString()); }It's a null dereference. What you're doing is essentially Object o = null; writeln(o.toString()); -Lars
May 03 2010
On 04/05/10 08:57, Lars T. Kyllingstad wrote:On Mon, 03 May 2010 15:54:28 -0500, Ellery Newcomer wrote:I believe his problem is that the return code of the caller indicates success.Hello. I'm trying to invoke a command inside d, and it returns a success code when the command in question segfaults. any ideas? // the caller import std.process; int main(){ auto r = system("./test"); return(r); } //test.d import std.stdio; void main() { Object o; writeln(o.toString()); }It's a null dereference. What you're doing is essentially Object o = null; writeln(o.toString()); -Lars
May 03 2010
On Mon, 03 May 2010 17:25:30 -0400, Bernard Helyer <b.helyer gmail.com> wrote:On 04/05/10 08:57, Lars T. Kyllingstad wrote:Could it be perhaps that it can't possibly get at that status? Remember, system runs /bin/sh -c, so all you can get as status is the return code of /bin/sh (which didn't segfault). -SteveOn Mon, 03 May 2010 15:54:28 -0500, Ellery Newcomer wrote:I believe his problem is that the return code of the caller indicates success.Hello. I'm trying to invoke a command inside d, and it returns a success code when the command in question segfaults. any ideas? // the caller import std.process; int main(){ auto r = system("./test"); return(r); } //test.d import std.stdio; void main() { Object o; writeln(o.toString()); }It's a null dereference. What you're doing is essentially Object o = null; writeln(o.toString()); -Lars
May 03 2010
On 04/05/10 09:49, Steven Schveighoffer wrote:On Mon, 03 May 2010 17:25:30 -0400, Bernard Helyer <b.helyer gmail.com> wrote:sh -c returns failure if the specified executable segfaults.I believe his problem is that the return code of the caller indicates success.Could it be perhaps that it can't possibly get at that status? Remember, system runs /bin/sh -c, so all you can get as status is the return code of /bin/sh (which didn't segfault). -Steve
May 03 2010
On 05/03/2010 04:49 PM, Steven Schveighoffer wrote:Could it be perhaps that it can't possibly get at that status? Remember, system runs /bin/sh -c, so all you can get as status is the return code of /bin/sh (which didn't segfault). -SteveAll I know is the analogous code in python returns the expected 139
May 03 2010
On Mon, 03 May 2010 17:34:51 -0500, Ellery Newcomer wrote:On 05/03/2010 04:49 PM, Steven Schveighoffer wrote:What OS are you running on? In D2, this the definition of system(): int system(string command) { if (!command) return std.c.process.system (null); const commandz = toStringz (command); invariant status = std.c.process.system (commandz); if (status == -1) return status; version (Posix) return (status & 0x0000ff00) >>> 8; else return status; } And "(139 & 0x0000ff00) >>> 8" evaluates to 0. I am not sure why it's not simply returning the raw status-code, though, and only on Posix systems -- it must be a Posix-ism I'm not familiar with. GrahamCould it be perhaps that it can't possibly get at that status? Remember, system runs /bin/sh -c, so all you can get as status is the return code of /bin/sh (which didn't segfault). -SteveAll I know is the analogous code in python returns the expected 139
May 03 2010
On 05/03/2010 06:08 PM, Graham Fawcett wrote:What OS are you running on? In D2, this the definition of system(): int system(string command) { if (!command) return std.c.process.system (null); const commandz = toStringz (command); invariant status = std.c.process.system (commandz); if (status == -1) return status; version (Posix) return (status& 0x0000ff00)>>> 8; else return status; } And "(139& 0x0000ff00)>>> 8" evaluates to 0. I am not sure why it's not simply returning the raw status-code, though, and only on Posix systems -- it must be a Posix-ism I'm not familiar with. GrahamI'm on fedora, and yeah, I guess it's a posixism. investigation yields lower 16 bits is coredump flag and signal code upper 16 bits is status code I tell ya, working with D, ya learn something new every day [while implementing crap that the provided libraries should handle on their own...]
May 03 2010
On Mon, 03 May 2010 20:32:03 -0500, Ellery Newcomer wrote:On 05/03/2010 06:08 PM, Graham Fawcett wrote:That hardcoded bit shift in std.process is really ugly, and hides what is going on. Here's the correct way to analyse POSIX status codes: import core.sys.posix.sys.wait; ... if (WIFEXITED(status)) writeln("Process exited with code ", WEXITSTATUS(status)); else if (WIFSIGNALED(status)) writeln("Process terminated by signal ", WTERMSIG(status)); In your case the segfault would cause SIGSEGV (signal 11) to be sent to the process, and the the above test would print "Process terminated by signal 11". See "man wait" for more info.[...] And "(139& 0x0000ff00)>>> 8" evaluates to 0. I am not sure why it's not simply returning the raw status-code, though, and only on Posix systems -- it must be a Posix-ism I'm not familiar with. GrahamI'm on fedora, and yeah, I guess it's a posixism. investigation yields lower 16 bits is coredump flag and signal code upper 16 bits is status codeI tell ya, working with D, ya learn something new every day [while implementing crap that the provided libraries should handle on their own...]std.process is currently undergoing a complete redesign, so the current situation should improve in the near future. :) -Lars
May 03 2010
On 05/04/2010 01:58 AM, Lars T. Kyllingstad wrote:In your case the segfault would cause SIGSEGV (signal 11) to be sent to the process, and the the above test would print "Process terminated by signal 11". See "man wait" for more info.That's where I got my info (or rather /usr/include/bits/waitstatus.h)std.process is currently undergoing a complete redesign, so the current situation should improve in the near future. :) -LarsThat's good to hear. And since you're an expert in this stuff, does this my code look alright? import std.typecons; static import std.c.process; import std.functional; import std.stdio; import std.string; alias Tuple!(ubyte, "status",ubyte, "term", ubyte, "sig",bool,"signaled",bool, "stopped", bool,"continued",bool, "coredumped") PID; PID toPID(int p){ PID pid; pid.status = cast(byte)((p & 0xff00) >> 8); pid.term = cast(byte)(p & 0xff); pid.sig = cast(byte)(p & 0x7f); pid.signaled = pid.sig != 0 && pid.sig != 0x7f; pid.coredumped = cast(bool)(p & 0x80); pid.stopped = pid.term == 0x7f; pid.continued = p == 0xffff; return pid; } int fromPID(PID pid){ if(pid.signaled) return pid.term; return pid.status; } alias compose!(toPID, std.c.process.system, toStringz) system_p; alias compose!(fromPID, system_p) system;
May 04 2010
On Tue, 04 May 2010 08:55:36 -0500, Ellery Newcomer wrote:On 05/04/2010 01:58 AM, Lars T. Kyllingstad wrote:Thanks for posting this. Just curious -- why did you choose to model PID as a tuple instead of a struct? I'm not clear on what the tradeoffs are. Best, GrahamIn your case the segfault would cause SIGSEGV (signal 11) to be sent to the process, and the the above test would print "Process terminated by signal 11". See "man wait" for more info.That's where I got my info (or rather /usr/include/bits/waitstatus.h)std.process is currently undergoing a complete redesign, so the current situation should improve in the near future. :) -LarsThat's good to hear. And since you're an expert in this stuff, does this my code look alright? import std.typecons; static import std.c.process; import std.functional; import std.stdio; import std.string; alias Tuple!(ubyte, "status",ubyte, "term", ubyte, "sig",bool,"signaled",bool, "stopped", bool,"continued",bool, "coredumped") PID; PID toPID(int p){ PID pid; pid.status = cast(byte)((p & 0xff00) >> 8); pid.term = cast(byte)(p & 0xff); pid.sig = cast(byte)(p & 0x7f); pid.signaled = pid.sig != 0 && pid.sig != 0x7f; pid.coredumped = cast(bool)(p & 0x80); pid.stopped = pid.term == 0x7f; pid.continued = p == 0xffff; return pid; } int fromPID(PID pid){ if(pid.signaled) return pid.term; return pid.status; } alias compose!(toPID, std.c.process.system, toStringz) system_p; alias compose!(fromPID, system_p) system;
May 04 2010
On 05/04/2010 09:51 AM, Graham Fawcett wrote:Thanks for posting this. Just curious -- why did you choose to model PID as a tuple instead of a struct? I'm not clear on what the tradeoffs are. Best, Grahamaccording to core.sys.posix.sys.wait, this is only valid for linux, grrr. I don't think there is a difference, as a tuple is a glorified struct. You just have to remember to use t.field instead of t.tupleof when iterating the elements in a foreach. Mostly, I just love one liners.
May 04 2010
On Tue, 04 May 2010 08:55:36 -0500, Ellery Newcomer wrote:On 05/04/2010 01:58 AM, Lars T. Kyllingstad wrote:Shouldn't 'term' and 'signaled' switch names? It looks to me like 'term' will be nonzero if the process receives any signal, while 'signaled' will be only be true if it is a terminating signal, and not if it is a stop signal. Otherwise it looks right, at least on Linux. But why not use the core.sys.posix.sys.wait.Wxxx() functions? Then it will automatically work on BSD and MacOS as well.std.process is currently undergoing a complete redesign, so the current situation should improve in the near future. :) -LarsThat's good to hear. And since you're an expert in this stuff, does this my code look alright? import std.typecons; static import std.c.process; import std.functional; import std.stdio; import std.string; alias Tuple!(ubyte, "status",ubyte, "term", ubyte, "sig",bool,"signaled",bool, "stopped", bool,"continued",bool, "coredumped") PID; PID toPID(int p){ PID pid; pid.status = cast(byte)((p & 0xff00) >> 8); pid.term = cast(byte)(p & 0xff); pid.sig = cast(byte)(p & 0x7f); pid.signaled = pid.sig != 0 && pid.sig != 0x7f; pid.coredumped = cast(bool)(p & 0x80); pid.stopped = pid.term == 0x7f; pid.continued = p == 0xffff; return pid; }int fromPID(PID pid){ if(pid.signaled) return pid.term; return pid.status; } alias compose!(toPID, std.c.process.system, toStringz) system_p; alias compose!(fromPID, system_p) system;I didn't know about compose, that's nifty. :) -Lars
May 04 2010
On 05/04/2010 11:32 AM, Lars T. Kyllingstad wrote:Shouldn't 'term' and 'signaled' switch names? It looks to me like 'term' will be nonzero if the process receives any signal, while 'signaled' will be only be true if it is a terminating signal, and not if it is a stop signal.signaled corresponds to WIFSIGNALED, whatever that is, and takes its name. term has no justification for its name; I just want something that is the same as what bash returns on segfault. I don't know what it does on BSD, though.Otherwise it looks right, at least on Linux. But why not use the core.sys.posix.sys.wait.Wxxx() functions? Then it will automatically work on BSD and MacOS as well.Easy, I didn't know about that module when I wrote this. alias Tuple!(int, "status",int, "signal", int, "termsig",bool, "signaled",bool, "stopped", bool,"continued") PID; PID toPID(int p){ PID pid; pid.status = WEXITSTATUS(p); pid.signal = (p & 0xff); pid.termsig = WTERMSIG(p); pid.signaled = WIFSIGNALED(p); pid.stopped = WIFSTOPPED(p); pid.continued = cast(bool) WIFCONTINUED(p); //why the eff is this defined as an int? return pid; } Is the coredump flag a linux-only thing?
May 04 2010
On Tue, 04 May 2010 15:22:52 -0500, Ellery Newcomer wrote:On 05/04/2010 11:32 AM, Lars T. Kyllingstad wrote:Don't know. Since all the other WIF* tests return bool, that looks like a bug.Shouldn't 'term' and 'signaled' switch names? It looks to me like 'term' will be nonzero if the process receives any signal, while 'signaled' will be only be true if it is a terminating signal, and not if it is a stop signal.signaled corresponds to WIFSIGNALED, whatever that is, and takes its name. term has no justification for its name; I just want something that is the same as what bash returns on segfault. I don't know what it does on BSD, though.Otherwise it looks right, at least on Linux. But why not use the core.sys.posix.sys.wait.Wxxx() functions? Then it will automatically work on BSD and MacOS as well.Easy, I didn't know about that module when I wrote this. alias Tuple!(int, "status",int, "signal", int, "termsig",bool, "signaled",bool, "stopped", bool,"continued") PID; PID toPID(int p){ PID pid; pid.status = WEXITSTATUS(p); pid.signal = (p & 0xff); pid.termsig = WTERMSIG(p); pid.signaled = WIFSIGNALED(p); pid.stopped = WIFSTOPPED(p); pid.continued = cast(bool) WIFCONTINUED(p); //why the eff is this defined as an int?return pid; } Is the coredump flag a linux-only thing?No, it exists in BSD and MacOS as well, but it's not a part of the POSIX specification. I assume that's why Sean didn't include it in the druntime headers. According to the man page it's not available on AIX and SunOS, and probably others. -Lars
May 05 2010
On Tue, 04 May 2010 09:25:30 +1200, Bernard Helyer wrote:On 04/05/10 08:57, Lars T. Kyllingstad wrote:Note to self: Read posts *thoroughly* before answering. Man, I was feeling so pleased with myself for having spotted the error so quickly. ;) -LarsOn Mon, 03 May 2010 15:54:28 -0500, Ellery Newcomer wrote:I believe his problem is that the return code of the caller indicates success.Hello. I'm trying to invoke a command inside d, and it returns a success code when the command in question segfaults. any ideas? [...]It's a null dereference. [...]
May 03 2010