Skip to content

stackMonitor::getCallStacks() always return empty results #484

Open
@Yukinarii

Description

@Yukinarii

I am trying to get the CallStack when a state fork happens. I modified ExecutionTracer::onFork() and tried to invoke stackMonitor::getCallStacks(). However, the size of the returned callStacks is always 0. Here is the code:

void ExecutionTracer::onFork(S2EExecutionState *state, const std::vector<S2EExecutionState *> &newStates,
                             const std::vector<klee::ref<klee::Expr>> &newConditions) {
...
StackMonitor::CallStacks callStacks;
    if (!m_stMonitor->getCallStacks(state, callStacks)) {
        getInfoStream(state) << "fail to get CallStack\n";
    }
    getInfoStream(state) << callStacks.size() << "\n";
...
}

I digged into the code base to try understanding what happened under the hood. I realized that m_stacks in StackMonitorState is always empty. The reason is that whenever StackMonitorState::update() is invoked, it failed to get the stack base and size from BaseLInuxMonitor::getCurrentStack(). And it fails to get this because it does not find any memory region information for the interested pid and stack pointer. One of the log messages I got is as follow:

195 [State 0] StackMonitor: could not get current stack
195 [State 0] StackMonitor: update pid=0x7f0 tid=0x7f0000007f0 pc=0x7f7ed5e37839 sp=0x7ffdbc7fa530 newFrame=0
195 [State 0] LinuxMonitor: cannot find corresponding memory region, m_map of 0x7f0
195 [State 0] MemoryMap: Dumping memory map for pid 2032
pid=0x7f0 [0x5600ac3ea000, 0x5600ac3eafff] R--
pid=0x7f0 [0x5600ac3eb000, 0x5600ac3ebfff] R-X
pid=0x7f0 [0x5600ac3ec000, 0x5600ac3edfff] R--
pid=0x7f0 [0x5600ac3ee000, 0x5600ac3eefff] RW-
pid=0x7f0 [0x7f7ed5d66000, 0x7f7ed5d69fff] RW-
pid=0x7f0 [0x7f7ed5d6a000, 0x7f7ed5d6bfff] R--
pid=0x7f0 [0x7f7ed5d6c000, 0x7f7ed5d7cfff] R-X
pid=0x7f0 [0x7f7ed5d7d000, 0x7f7ed5d82fff] R--
pid=0x7f0 [0x7f7ed5d83000, 0x7f7ed5d83fff] ---
pid=0x7f0 [0x7f7ed5d84000, 0x7f7ed5d84fff] R--
pid=0x7f0 [0x7f7ed5d85000, 0x7f7ed5d85fff] RW-
pid=0x7f0 [0x7f7ed5d86000, 0x7f7ed5d88fff] R--
pid=0x7f0 [0x7f7ed5d89000, 0x7f7ed5d9cfff] R-X
pid=0x7f0 [0x7f7ed5d9d000, 0x7f7ed5da0fff] R--
pid=0x7f0 [0x7f7ed5da1000, 0x7f7ed5da1fff] ---
pid=0x7f0 [0x7f7ed5da2000, 0x7f7ed5da2fff] R--
pid=0x7f0 [0x7f7ed5da3000, 0x7f7ed5da3fff] RW-
pid=0x7f0 [0x7f7ed5da4000, 0x7f7ed5da4fff] R--
pid=0x7f0 [0x7f7ed5da5000, 0x7f7ed5da5fff] R-X
pid=0x7f0 [0x7f7ed5da6000, 0x7f7ed5da7fff] R--
pid=0x7f0 [0x7f7ed5da8000, 0x7f7ed5da8fff] RW-
pid=0x7f0 [0x7f7ed5da9000, 0x7f7ed5dd0fff] R--
pid=0x7f0 [0x7f7ed5dd1000, 0x7f7ed5f65fff] R-X
pid=0x7f0 [0x7f7ed5f66000, 0x7f7ed5fc1fff] R--
pid=0x7f0 [0x7f7ed5fc2000, 0x7f7ed5fd0fff] RW-
pid=0x7f0 [0x7f7ed5fd9000, 0x7f7ed5fdafff] R--
pid=0x7f0 [0x7f7ed5fdb000, 0x7f7ed5fdefff] R-X
pid=0x7f0 [0x7f7ed5fdf000, 0x7f7ed5fdffff] R--
pid=0x7f0 [0x7f7ed5fe0000, 0x7f7ed5fe0fff] ---
pid=0x7f0 [0x7f7ed5fe1000, 0x7f7ed5fe1fff] R--
pid=0x7f0 [0x7f7ed5fe2000, 0x7f7ed5fe4fff] RW-
pid=0x7f0 [0x7f7ed5fe5000, 0x7f7ed5fe6fff] R--
pid=0x7f0 [0x7f7ed5fe7000, 0x7f7ed6010fff] R-X
pid=0x7f0 [0x7f7ed6011000, 0x7f7ed601bfff] R--
pid=0x7f0 [0x7f7ed601d000, 0x7f7ed601efff] R--
pid=0x7f0 [0x7f7ed601f000, 0x7f7ed6020fff] RW-

Apparently, the stack pointer 0x7ffdbc7fa530 does not fall into any of the memory regions in the memory map. I am not sure if I miss anything to make this problem. So my question is: How can I get the correct callStacks with stackMonitor::getCallStacks()?

Here is the simple program I am trying to symbolic execute:

#include <stdio.h>
#include <string.h>
#include <s2e/s2e.h>

void test() {

    char str[3] = { 0 };
    s2e_make_symbolic(str, 2, "str");

    if (str[0] == '\n' || str[1] == '\n') {
        printf("Not enough characters\n");
    } else {
        if (str[0] >= 'a' && str[0] <= 'z') {
            printf("First char is lowercase\n");
        } else {
            printf("First char is not lowercase\n");
        }

        if (str[0] >= '0' && str[0] <= '9') {
            printf("First char is a digit\n");
        } else {
            printf("First char is not a digit\n");
        }

        if (str[0] == str[1]) {
            printf("First and second chars are the same\n");
        } else {
            printf("First and second chars are not the same\n");
        }
    }

    s2e_get_example(str, 2);
    printf("'%c%c' %02x %02x\n", str[0], str[1],
           (unsigned char) str[0], (unsigned char) str[1]);
}

int main(void) {
	test();
	return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions