From e9bd6dc177152cb65625caa4679552a743c30f51 Mon Sep 17 00:00:00 2001 From: Peter Goodman Date: Tue, 12 Dec 2017 14:01:41 -0500 Subject: [PATCH] Fixes one or two subtle issues. But the more interesting fix is that I implemented puts in terms of DeepState_Log. Calls to printf that had no format arguments are transformed by the compiler into calls to puts, but that wasn't being wrapped by DeepState, so it was appearing as though those log messages never actually happened. --- bin/deepstate/common.py | 21 ++++++----- examples/OneOf.cpp | 54 ++++++++++++++--------------- examples/StreamingAndFormatting.cpp | 5 +-- src/lib/Log.c | 6 ++++ 4 files changed, 47 insertions(+), 39 deletions(-) diff --git a/bin/deepstate/common.py b/bin/deepstate/common.py index e62f7ba..5c63862 100644 --- a/bin/deepstate/common.py +++ b/bin/deepstate/common.py @@ -270,10 +270,11 @@ class DeepState(object): new_bytes = [] for b in byte_str: if isinstance(b, str): - assert len(b) == 1 - new_bytes.append(ord(b)) + new_bytes.extend(ord(bn) for bn in b) elif isinstance(b, (int, long)): new_bytes.append(b) + elif isinstance(b, (list, tuple)): + new_bytes.extend(self._concretize_bytes(b)) else: new_bytes.append(self.concretize(b, constrain=True)) return new_bytes @@ -303,9 +304,11 @@ class DeepState(object): format_str = format_str.replace('z', '') format_str = format_str.replace('t', '') - message.extend(format_str % val) + message.append(format_str % val) - return "".join(message) + res = "".join(message) + res.rstrip("\r\n") + return res def _save_test(self, info, input_bytes): """Save the concretized bytes to a file.""" @@ -495,7 +498,7 @@ class DeepState(object): level = self.concretize(level, constrain=True) ea = self.concretize(ea, constrain=True) assert level in LOG_LEVEL_TO_LOGGER - self.log_message(level, self.read_c_string(ea, concretize=False)) + self.log_message(level, self.read_c_string(ea, concretize=False)[0]) if level == LOG_LEVEL_FATAL: self.api_fail() @@ -513,8 +516,8 @@ class DeepState(object): unpack_ea = self.concretize(unpack_ea, constrain=True) uint64_ea = self.concretize(uint64_ea, constrain=True) - format_str, _ = self.read_c_string(format_ea) - unpack_str, _ = self.read_c_string(unpack_ea) + format_str = self.read_c_string(format_ea)[0] + unpack_str = self.read_c_string(unpack_ea)[0] uint64_bytes = [] for i in xrange(8): b, _ = self.read_uint8_t(uint64_ea + i, concretize=False) @@ -545,8 +548,8 @@ class DeepState(object): format_ea = self.concretize(format_ea, constrain=True) str_ea = self.concretize(str_ea, constrain=True) - format_str, _ = self.read_c_string(format_ea) - print_str, _ = self.read_c_string(str_ea, concretize=False) + format_str = self.read_c_string(format_ea)[0] + print_str = self.read_c_string(str_ea, concretize=False)[0] stream_id = 'stream_{}'.format(level) stream = list(self.context[stream_id]) diff --git a/examples/OneOf.cpp b/examples/OneOf.cpp index 893e49d..c2cce83 100644 --- a/examples/OneOf.cpp +++ b/examples/OneOf.cpp @@ -30,35 +30,33 @@ TEST(OneOfExample, ProduceSixtyOrHigher) { // Add this back in and uncomment out choices parts below, add // & choices, N to captures, and it becomes quite difficult. - int N = 0; - while (N < LENGTH) { - N++; + for (int N = 0;N < LENGTH; N++) { OneOf( - [&x] { - x += 1; - printf("-1\n"); - //choices[N] = '+'; - }, - [&x] { - x -= 1; - printf("+1\n"); - //choices[N] = '-'; - }, - [&x] { - x *= 2; - printf("*2\n"); - //choices[N] = '2'; - }, - [&x] { - x += 10; - printf("+=10\n"); - //choices[N] = 'x'; - }, - [&x] { - x = 0; - printf("=0\n"); - //choices[N] = '0'; - }); + [&x] { + x += 1; + printf("+=1\n"); + //choices[N] = '+'; + }, + [&x] { + x -= 1; + printf("-=1\n"); + //choices[N] = '-'; + }, + [&x] { + x *= 2; + printf("*2\n"); + //choices[N] = '2'; + }, + [&x] { + x += 10; + printf("+=10\n"); + //choices[N] = 'x'; + }, + [&x] { + x = 0; + printf("=0\n"); + //choices[N] = '0'; + }); //choices[N+1] = 0; ASSERT_LE(x, 60) diff --git a/examples/StreamingAndFormatting.cpp b/examples/StreamingAndFormatting.cpp index 960aa70..da5487c 100644 --- a/examples/StreamingAndFormatting.cpp +++ b/examples/StreamingAndFormatting.cpp @@ -15,7 +15,7 @@ */ #include - +/* TEST(Streaming, BasicLevels) { LOG(DEBUG) << "This is a debug message"; LOG(INFO) << "This is an info message"; @@ -32,11 +32,12 @@ TEST(Streaming, BasicTypes) { LOG(INFO) << "string"; LOG(INFO) << nullptr; } - +*/ TEST(Formatting, OverridePrintf) { printf("hello string=%s hex_lower=%x hex_upper=%X octal=%o char=%c dec=%d" "double=%f sci=%e SCI=%E pointer=%p", "world", 999, 999, 999, 'a', 999, 999.0, 999.0, 999.0, "world"); + printf("hello again!"); } int main(void) { diff --git a/src/lib/Log.c b/src/lib/Log.c index 6ba7403..95056a2 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -100,6 +100,12 @@ void DeepState_LogFormat(enum DeepState_LogLevel level, } /* Override libc! */ +DEEPSTATE_NOINLINE +int puts(const char *str) { + DeepState_Log(DeepState_LogInfo, str); + return 0; +} + DEEPSTATE_NOINLINE int printf(const char *format, ...) { va_list args;