Skip to content

Commit 80d13c7

Browse files
committed
fix: allocate stack chunk always
1 parent c821f88 commit 80d13c7

1 file changed

Lines changed: 18 additions & 19 deletions

File tree

echion/stack_chunk.h

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@
77
#define PY_SSIZE_T_CLEAN
88
#include <Python.h>
99

10+
// Python 3.13+ stack chunk minimum size (16KB)
11+
// This is the minimum size of a stack chunk from Python's implementation
12+
// https://github.com/python/cpython/blob/f6536d48cd294f3dea6a4ecfd8148aa505dbb581/Python/pystate.c#L1417
13+
#define _PY_DATA_STACK_CHUNK_SIZE (16 * 1024)
14+
1015
#include <exception>
1116
#include <memory>
17+
#include <vector>
1218

1319
#include <echion/vm.h>
1420

@@ -27,21 +33,19 @@ class StackChunkError : public std::exception
2733
class StackChunk
2834
{
2935
public:
30-
StackChunk() {}
36+
StackChunk()
37+
{
38+
// Initialize with Python's minimum stack chunk size
39+
data_capacity = _PY_DATA_STACK_CHUNK_SIZE;
40+
data.resize(data_capacity);
41+
}
3142

3243
inline void update(_PyStackChunk* chunk_addr);
3344
inline void* resolve(void* frame_addr);
3445

3546
private:
3647
void* origin = NULL;
37-
struct FreeDeleter
38-
{
39-
void operator()(void* ptr) const
40-
{
41-
free(ptr);
42-
}
43-
};
44-
std::unique_ptr<char[], FreeDeleter> data = nullptr;
48+
std::vector<char> data;
4549
size_t data_capacity = 0;
4650
std::unique_ptr<StackChunk> previous = nullptr;
4751
};
@@ -58,18 +62,13 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
5862
// if data_size is not enough, reallocate
5963
if (chunk.size > data_capacity)
6064
{
61-
data_capacity = chunk.size;
62-
char* new_data = (char*)realloc(data.get(), data_capacity);
63-
if (!new_data)
64-
{
65-
throw StackChunkError();
66-
}
67-
data.release(); // Release the old pointer before resetting
68-
data.reset(new_data);
65+
data_capacity =
66+
std::max(chunk.size, data_capacity); // Use max to maintain minimum capacity
67+
data.resize(data_capacity);
6968
}
7069

7170
// Copy the data up until the size of the chunk
72-
if (copy_generic(chunk_addr, data.get(), chunk.size))
71+
if (copy_generic(chunk_addr, data.data(), chunk.size))
7372
throw StackChunkError();
7473

7574
if (chunk.previous != NULL)
@@ -90,7 +89,7 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
9089
// ----------------------------------------------------------------------------
9190
void* StackChunk::resolve(void* address)
9291
{
93-
_PyStackChunk* chunk = (_PyStackChunk*)data.get();
92+
_PyStackChunk* chunk = (_PyStackChunk*)data.data();
9493

9594
// Check if this chunk contains the address
9695
if (address >= origin && address < (char*)origin + chunk->size)

0 commit comments

Comments
 (0)