Fixes to stream formatting of doubles, they weren't being streamed before. Implemented the chk versions of printf and such, so that they all route through the logging interface as well. Implemented the concretization APIs.
This commit is contained in:
+9
-6
@@ -186,14 +186,17 @@ int DeepState_IsSymbolicUInt(uint32_t x) {
|
||||
}
|
||||
|
||||
/* Defined in Stream.c */
|
||||
extern void _DeepState_StreamInt(enum DeepState_LogLevel level, const char *format,
|
||||
const char *unpack, uint64_t *val);
|
||||
extern void _DeepState_StreamInt(enum DeepState_LogLevel level,
|
||||
const char *format,
|
||||
const char *unpack, uint64_t *val);
|
||||
|
||||
extern void _DeepState_StreamFloat(enum DeepState_LogLevel level, const char *format,
|
||||
const char *unpack, double *val);
|
||||
extern void _DeepState_StreamFloat(enum DeepState_LogLevel level,
|
||||
const char *format,
|
||||
const char *unpack, double *val);
|
||||
|
||||
extern void _DeepState_StreamString(enum DeepState_LogLevel level, const char *format,
|
||||
const char *str);
|
||||
extern void _DeepState_StreamString(enum DeepState_LogLevel level,
|
||||
const char *format,
|
||||
const char *str);
|
||||
|
||||
/* A DeepState-specific symbol that is needed for hooking. */
|
||||
struct DeepState_IndexEntry {
|
||||
|
||||
+86
-24
@@ -14,12 +14,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Helps to avoid conflicting declaration types of `__printf_chk`. */
|
||||
#define printf printf_foo
|
||||
#define vprintf vprintf_foo
|
||||
#define fprintf fprintf_foo
|
||||
#define vfprintf vfprintf_foo
|
||||
#define __printf_chk __printf_chk_foo
|
||||
#define __vprintf_chk __vprintf_chk_foo
|
||||
#define __fprintf_chk __fprintf_chk_foo
|
||||
#define __vfprintf_chk __vfprintf_chk_foo
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "deepstate/DeepState.h"
|
||||
|
||||
#undef printf
|
||||
#undef vprintf
|
||||
#undef fprintf
|
||||
#undef vfprintf
|
||||
#undef __printf_chk
|
||||
#undef __vprintf_chk
|
||||
#undef __fprintf_chk
|
||||
#undef __vfprintf_chk
|
||||
|
||||
DEEPSTATE_BEGIN_EXTERN_C
|
||||
|
||||
/* Returns a printable string version of the log level. */
|
||||
@@ -47,9 +66,10 @@ enum {
|
||||
char DeepState_LogBuf[DeepState_LogBufSize + 1] = {};
|
||||
|
||||
/* Log a C string. */
|
||||
DEEPSTATE_NOINLINE
|
||||
void DeepState_Log(enum DeepState_LogLevel level, const char *str) {
|
||||
memset(DeepState_LogBuf, 0, DeepState_LogBufSize);
|
||||
snprintf(DeepState_LogBuf, DeepState_LogBufSize, "%s: %s",
|
||||
snprintf(DeepState_LogBuf, DeepState_LogBufSize, "%s: %s\n",
|
||||
DeepState_LogLevelStr(level), str);
|
||||
fputs(DeepState_LogBuf, stderr);
|
||||
|
||||
@@ -61,48 +81,90 @@ void DeepState_Log(enum DeepState_LogLevel level, const char *str) {
|
||||
}
|
||||
|
||||
/* Log some formatted output. */
|
||||
void DeepState_LogFormat(enum DeepState_LogLevel level, const char *format, ...) {
|
||||
DEEPSTATE_NOINLINE
|
||||
void DeepState_LogVFormat(enum DeepState_LogLevel level,
|
||||
const char *format, va_list args) {
|
||||
DeepState_LogStream(level);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
DeepState_StreamVFormat(level, format, args);
|
||||
va_end(args);
|
||||
DeepState_LogStream(level);
|
||||
}
|
||||
|
||||
/* Log some formatted output. */
|
||||
void DeepState_LogVFormat(enum DeepState_LogLevel level,
|
||||
const char *format, va_list args) {
|
||||
DeepState_LogStream(level);
|
||||
DeepState_StreamVFormat(level, format, args);
|
||||
DeepState_LogStream(level);
|
||||
DEEPSTATE_NOINLINE
|
||||
void DeepState_LogFormat(enum DeepState_LogLevel level,
|
||||
const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
DeepState_LogVFormat(level, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* Override libc! */
|
||||
DEEPSTATE_NOINLINE
|
||||
int printf(const char *format, ...) {
|
||||
DeepState_LogStream(DeepState_LogInfo);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
DeepState_StreamVFormat(DeepState_LogInfo, format, args);
|
||||
DeepState_LogVFormat(DeepState_LogInfo, format, args);
|
||||
va_end(args);
|
||||
DeepState_LogStream(DeepState_LogInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fprintf(FILE *file, const char *format, ...) {
|
||||
enum DeepState_LogLevel level = DeepState_LogInfo;
|
||||
if (stderr == file) {
|
||||
level = DeepState_LogDebug;
|
||||
} else if (stdout != file) {
|
||||
return 0; /* TODO(pag): This is probably evil. */
|
||||
}
|
||||
|
||||
DeepState_LogStream(level);
|
||||
DEEPSTATE_NOINLINE
|
||||
int __printf_chk(int flag, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
DeepState_StreamVFormat(level, format, args);
|
||||
DeepState_LogVFormat(DeepState_LogInfo, format, args);
|
||||
va_end(args);
|
||||
DeepState_LogStream(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEEPSTATE_NOINLINE
|
||||
int vprintf(const char *format, va_list args) {
|
||||
DeepState_LogVFormat(DeepState_LogInfo, format, args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEEPSTATE_NOINLINE
|
||||
int __vprintf_chk(int flag, const char *format, va_list args) {
|
||||
DeepState_LogVFormat(DeepState_LogInfo, format, args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEEPSTATE_NOINLINE
|
||||
int vfprintf(FILE *file, const char *format, va_list args) {
|
||||
if (stderr == file) {
|
||||
DeepState_LogVFormat(DeepState_LogDebug, format, args);
|
||||
} else if (stdout == file) {
|
||||
DeepState_LogVFormat(DeepState_LogInfo, format, args);
|
||||
} else {
|
||||
DeepState_LogStream(DeepState_LogWarning);
|
||||
DeepState_Log(DeepState_LogWarning,
|
||||
"Ignorning vfprintf with non-stdout/stderr stream.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEEPSTATE_NOINLINE
|
||||
int fprintf(FILE *file, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(file, format, args);
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEEPSTATE_NOINLINE
|
||||
int __fprintf_chk(int flag, FILE *file, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(file, format, args);
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEEPSTATE_NOINLINE
|
||||
int __vfprintf_chk(int flag, FILE *file, const char *format, va_list args) {
|
||||
vfprintf(file, format, args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -255,8 +255,7 @@ void DeepState_StreamDouble(enum DeepState_LogLevel level, double val) {
|
||||
void DeepState_LogStream(enum DeepState_LogLevel level) {
|
||||
struct DeepState_Stream *stream = &(DeepState_Streams[level]);
|
||||
if (stream->size) {
|
||||
stream->message[stream->size] = '\n';
|
||||
stream->message[stream->size + 1] = '\0';
|
||||
stream->message[stream->size] = '\0';
|
||||
stream->message[DeepState_StreamSize] = '\0';
|
||||
DeepState_Log(level, stream->message);
|
||||
memset(stream->message, 0, DeepState_StreamSize);
|
||||
@@ -501,6 +500,8 @@ get_length_char:
|
||||
stream->value.as_fp64 = va_arg(args, double);
|
||||
}
|
||||
DeepState_StreamUnpack(stream, 'd');
|
||||
_DeepState_StreamFloat(level, format_buf, stream->unpack,
|
||||
&(stream->value.as_fp64));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
@@ -527,14 +528,19 @@ void DeepState_StreamVFormat(enum DeepState_LogLevel level, const char *format_,
|
||||
va_list args) {
|
||||
char *begin = NULL;
|
||||
char *end = NULL;
|
||||
char *format = DeepState_Format;
|
||||
char *format = &(DeepState_Format[0]);
|
||||
int i = 0;
|
||||
char ch = '\0';
|
||||
char next_ch = '\0';
|
||||
size_t len = strlen(format_);
|
||||
|
||||
strncpy(format, format_, DeepState_StreamSize);
|
||||
format[DeepState_StreamSize] = '\0';
|
||||
if (len >= DeepState_StreamSize) {
|
||||
DeepState_Abandon("Format string is too long.");
|
||||
}
|
||||
|
||||
/* Concretize the string format. */
|
||||
memcpy(format, format_, len);
|
||||
format[len] = '\0';
|
||||
DeepState_ConcretizeCStr(format);
|
||||
|
||||
for (i = 0; '\0' != (ch = format[i]); ) {
|
||||
|
||||
Reference in New Issue
Block a user