digitalmars.D.learn - object.Exception std/stdio.d(1321): Enforcement failed - I must be
- Colin Grogan (53/53) Aug 15 2013 Hi all,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (22/39) Aug 15 2013 ...
- Colin Grogan (63/109) Aug 15 2013 Hi Ali,
- Colin Grogan (13/138) Aug 15 2013 I should have put this here too:
- monarch_dodra (25/38) Aug 15 2013 This "scope(exit)" runs when you exit the scope, eg: the
- monarch_dodra (4/7) Aug 15 2013 Another issue is that printing a time will always allocate a
- Colin Grogan (7/15) Aug 15 2013 I've decided whats the point in printing a time that the file
Hi all, I've done this a million times (I thought!) but I'm getting a strange error I cant figure out. The code: void writeMsg(string msg){ logFile.writeln(msg); } is failing with this error: object.Exception std/stdio.d(1321): Enforcement failed ---------------- ./tester(pure safe bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)+0x6b) [0x49a343] ./tester(ref std.stdio.File.LockingTextWriter std.stdio.File.LockingTextWriter.__ctor(ref std.stdio.File)+0x59) [0x4ce019] ./tester( property std.stdio.File.LockingTextWriter std.stdio.File.lockingTextWriter()+0x29) [0x4ce179] ./tester(void std.stdio.File.write!(immutable(char)[], char).write(immutable(char)[], char)+0x69) [0x49b931] ./tester(void std.stdio.File.writeln!(immutable(char)[]).writeln(immutable(char)[])+0x67) [0x49b8bf] ./tester(void utils.log.Logger.writeMsg(immutable(char)[])+0x29) [0x494631] ./tester(void utils.log.Logger.log(utils.log.LogLevel, immutable(char)[])+0xa5) [0x4946dd] ./tester(void utils.log.Logger.logDebug(immutable(char)[])+0xa2) [0x49455a] ./tester(_Dmain+0x52) [0x4a3862] ./tester(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runMain()+0x18) [0x4bf79c] ./tester(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x4bf2ce] ./tester(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runAll()+0x40) [0x4bf7ec] ./tester(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x4bf2ce] ./tester(_d_run_main+0x1ae) [0x4bf28a] ./tester(main+0x17) [0x4bf0d7] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f6bcc3f176d] Also, I'm creating the logFile variable as follows: File logFile = File(fileName, "w"); If ye need the code around it I'll be glad to post it, but the logFile.writeln(msg) is the specific line it breaks on. If I comment that out all is good. It writes to the file once, and next time I call the function it fails. My guess is the lock on the file isn't releasing after the first write?
Aug 15 2013
On 08/15/2013 10:03 AM, Colin Grogan wrote:I've done this a million times (I thought!) but I'm getting a strange error I cant figure out. The code: void writeMsg(string msg){ logFile.writeln(msg);What is logFile?} is failing with this error: object.Exception std/stdio.d(1321): Enforcement failed ---------------- ./tester(pure safe bool std.exception.enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)+0x6b) [0x49a343] ./tester(ref std.stdio.File.LockingTextWriter std.stdio.File.LockingTextWriter.__ctor(ref std.stdio.File)+0x59) [0x4ce019]...Also, I'm creating the logFile variable as follows: File logFile = File(fileName, "w");That looks like a local variable. How does writeMsg see it?If ye need the code around it I'll be glad to post itIt is very helpful if you can reproduce it in a minimal example. The following program works with v2.064-devel-52cc287: import std.stdio; enum fileName = "deneme.txt"; File logFile; static this() { logFile = File(fileName, "w"); } void writeMsg(string msg){ logFile.writeln(msg); } void main() { writeMsg("hello"); writeMsg("world"); } Can you add to it and see when the problem appears. Ali
Aug 15 2013
Hi Ali, Heres my full Logger class. module utils.log; import std.stdio; import std.string; import std.datetime; public enum LogLevel {Fatal=0, Severe=1, Info=2, Debug=3, Verbose=4}; public class Logger{ public: this(LogLevel minLevel = LogLevel.Info, string fileName="logfile.log"){ this.minLevel = minLevel; logFile = File(fileName, "w"); this.writeMsg(format("Opened file for writing at [%s]", currTimestamp())); logFile.flush(); scope(exit){ logInfo("End log"); logFile.close(); } } void logFatal(string message){ this.log(LogLevel.Fatal, "FATAL - " ~ message); } void logSevere(string message){ this.log(LogLevel.Severe, "SEVERE - " ~ message); } void logInfo(string message){ this.log(LogLevel.Info, format("INFO - %s",message)); } void logDebug(string message){ this.log(LogLevel.Debug, "DEBUG - " ~ message); } void logVerbose(string message){ this.log(LogLevel.Verbose, "VERBOSE - " ~ message); } private: void writeMsg(string msg){ logFile.writeln(msg); } void log(LogLevel level, string message){ if(this.minLevel <= level){ writefln("Before write! %s",message); string timestamp = currTimestamp(); this.writeMsg(format("[%s] %s", timestamp, message)); writefln("After write! %s", message); logFile.flush(); } } string currTimestamp(){ auto currTime = Clock.currTime(); return currTime.toISOExtString()[0..$-8]; } private: LogLevel minLevel; File logFile; } logFile is a class variable, so its definatly visible. Ill go with adding to your code now and see at what point it breaks. Thanks! On Thursday, 15 August 2013 at 17:33:11 UTC, Ali Çehreli wrote:On 08/15/2013 10:03 AM, Colin Grogan wrote:I've done this a million times (I thought!) but I'm getting astrangeerror I cant figure out. The code: void writeMsg(string msg){ logFile.writeln(msg);What is logFile?} is failing with this error: object.Exception std/stdio.d(1321): Enforcement failed ---------------- ./tester(pure safe boolstd.exception.enforce!(bool).enforce(bool, lazyconst(char)[], immutable(char)[], ulong)+0x6b) [0x49a343] ./tester(ref std.stdio.File.LockingTextWriter std.stdio.File.LockingTextWriter.__ctor(refstd.stdio.File)+0x59)[0x4ce019]...Also, I'm creating the logFile variable as follows: File logFile = File(fileName, "w");That looks like a local variable. How does writeMsg see it?If ye need the code around it I'll be glad to post itIt is very helpful if you can reproduce it in a minimal example. The following program works with v2.064-devel-52cc287: import std.stdio; enum fileName = "deneme.txt"; File logFile; static this() { logFile = File(fileName, "w"); } void writeMsg(string msg){ logFile.writeln(msg); } void main() { writeMsg("hello"); writeMsg("world"); } Can you add to it and see when the problem appears. Ali
Aug 15 2013
I should have put this here too: My main function. import std.stdio; import utils.log; void main() { Logger log = new Logger(LogLevel.Info, "somefile.log"); log.logDebug("Test"); } When creating the log file, it prints the text in the constructor as expected, but the call to log.logDebug() fails. This is why I'm thinking its locking but not releasing? On Thursday, 15 August 2013 at 17:41:00 UTC, Colin Grogan wrote:Hi Ali, Heres my full Logger class. module utils.log; import std.stdio; import std.string; import std.datetime; public enum LogLevel {Fatal=0, Severe=1, Info=2, Debug=3, Verbose=4}; public class Logger{ public: this(LogLevel minLevel = LogLevel.Info, string fileName="logfile.log"){ this.minLevel = minLevel; logFile = File(fileName, "w"); this.writeMsg(format("Opened file for writing at [%s]", currTimestamp())); logFile.flush(); scope(exit){ logInfo("End log"); logFile.close(); } } void logFatal(string message){ this.log(LogLevel.Fatal, "FATAL - " ~ message); } void logSevere(string message){ this.log(LogLevel.Severe, "SEVERE - " ~ message); } void logInfo(string message){ this.log(LogLevel.Info, format("INFO - %s",message)); } void logDebug(string message){ this.log(LogLevel.Debug, "DEBUG - " ~ message); } void logVerbose(string message){ this.log(LogLevel.Verbose, "VERBOSE - " ~ message); } private: void writeMsg(string msg){ logFile.writeln(msg); } void log(LogLevel level, string message){ if(this.minLevel <= level){ writefln("Before write! %s",message); string timestamp = currTimestamp(); this.writeMsg(format("[%s] %s", timestamp, message)); writefln("After write! %s", message); logFile.flush(); } } string currTimestamp(){ auto currTime = Clock.currTime(); return currTime.toISOExtString()[0..$-8]; } private: LogLevel minLevel; File logFile; } logFile is a class variable, so its definatly visible. Ill go with adding to your code now and see at what point it breaks. Thanks! On Thursday, 15 August 2013 at 17:33:11 UTC, Ali Çehreli wrote:On 08/15/2013 10:03 AM, Colin Grogan wrote:I've done this a million times (I thought!) but I'm getting astrangeerror I cant figure out. The code: void writeMsg(string msg){ logFile.writeln(msg);What is logFile?} is failing with this error: object.Exception std/stdio.d(1321): Enforcement failed ---------------- ./tester(pure safe boolstd.exception.enforce!(bool).enforce(bool, lazyconst(char)[], immutable(char)[], ulong)+0x6b) [0x49a343] ./tester(ref std.stdio.File.LockingTextWriter std.stdio.File.LockingTextWriter.__ctor(refstd.stdio.File)+0x59)[0x4ce019]...Also, I'm creating the logFile variable as follows: File logFile = File(fileName, "w");That looks like a local variable. How does writeMsg see it?If ye need the code around it I'll be glad to post itIt is very helpful if you can reproduce it in a minimal example. The following program works with v2.064-devel-52cc287: import std.stdio; enum fileName = "deneme.txt"; File logFile; static this() { logFile = File(fileName, "w"); } void writeMsg(string msg){ logFile.writeln(msg); } void main() { writeMsg("hello"); writeMsg("world"); } Can you add to it and see when the problem appears. Ali
Aug 15 2013
On Thursday, 15 August 2013 at 17:41:00 UTC, Colin Grogan wrote:this(LogLevel minLevel = LogLevel.Info, string fileName="logfile.log") { this.minLevel = minLevel; logFile = File(fileName, "w"); this.writeMsg(format("Opened file for writing at [%s]", currTimestamp())); logFile.flush(); scope(exit){ logInfo("End log"); logFile.close(); } }This "scope(exit)" runs when you exit the scope, eg: the _constructor_, not when your log is destroyed. YOur constructor is basically leaving your log file in a closed state, making it useless. Instead, use a destroyer: ~this() { logInfo("End log"); logFile.close(); } Note though that this will not *actually* work, because since the destroyer is run during a collection run, you can't allocate, and logInfo calls format, which allocates. As a matter of fact, you should avoid calling format at all. Instead, your "writeMsg" should look like this void writeMsg(Args...)(string fmt, Args args){ logFile.writefln(fmt, args); } Then, in your log, instead of doing: this.writeMsg(format("[%s] %s", timestamp, message)); simply do: this.writeMsg("[%s] %s", timestamp, message); This doesn't fix everything though, and you should also rework your "logLevel" functions to not allocate: For example, by making "log" accept two strings.
Aug 15 2013
On Thursday, 15 August 2013 at 18:09:21 UTC, monarch_dodra wrote:This doesn't fix everything though, and you should also rework your "logLevel" functions to not allocate: For example, by making "log" accept two strings.Another issue is that printing a time will always allocate a string, so there is (currently) no way to log at what time the log file is closed, if you rely on the destructor.
Aug 15 2013
I've decided whats the point in printing a time that the file closed at, the last message will probably tell me that anyway if theres an error to find. Your suggestions worked perfectly, I've obviously a lot to learn on how to use the intricacies of D. Thanks very much! On Thursday, 15 August 2013 at 19:54:42 UTC, monarch_dodra wrote:On Thursday, 15 August 2013 at 18:09:21 UTC, monarch_dodra wrote:This doesn't fix everything though, and you should also rework your "logLevel" functions to not allocate: For example, by making "log" accept two strings.Another issue is that printing a time will always allocate a string, so there is (currently) no way to log at what time the log file is closed, if you rely on the destructor.
Aug 15 2013