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-
1510#include < exception>
1611#include < memory>
1712#include < vector>
@@ -33,15 +28,11 @@ class StackChunkError : public std::exception
3328class StackChunk
3429{
3530public:
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- }
31+ StackChunk () {}
4232
4333 inline void update (_PyStackChunk* chunk_addr);
4434 inline void * resolve (void * frame_addr);
35+ inline bool is_valid () const ;
4536
4637private:
4738 void * origin = NULL ;
@@ -58,12 +49,19 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
5849 if (copy_type (chunk_addr, chunk))
5950 throw StackChunkError ();
6051
52+ // Validate chunk size before proceeding
53+ if (chunk.size == 0 )
54+ {
55+ // Maybe the chunk is being created or freed
56+ return ;
57+ }
58+
6159 origin = chunk_addr;
60+
6261 // if data_size is not enough, reallocate
63- if (chunk.size > data_capacity || data. data () == nullptr )
62+ if (chunk.size > data_capacity)
6463 {
65- data_capacity =
66- std::max (chunk.size , data_capacity); // Use max to maintain minimum capacity
64+ data_capacity = std::max (chunk.size , data_capacity);
6765 data.resize (data_capacity);
6866 }
6967
@@ -89,13 +87,14 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
8987// ----------------------------------------------------------------------------
9088void * StackChunk::resolve (void * address)
9189{
92- _PyStackChunk* chunk = (_PyStackChunk*)data.data ();
93-
94- if (chunk == nullptr )
90+ // If data is not properly initialized, simply return the address
91+ if (!is_valid ())
9592 {
9693 return address;
9794 }
9895
96+ _PyStackChunk* chunk = (_PyStackChunk*)data.data ();
97+
9998 // Check if this chunk contains the address
10099 if (address >= origin && address < (char *)origin + chunk->size )
101100 return (char *)chunk + ((char *)address - (char *)origin);
@@ -106,6 +105,15 @@ void* StackChunk::resolve(void* address)
106105 return address;
107106}
108107
108+ // ----------------------------------------------------------------------------
109+ bool StackChunk::is_valid () const
110+ {
111+ return data_capacity > 0 &&
112+ data.size () > 0 &&
113+ data.data () != nullptr &&
114+ origin != nullptr ;
115+ }
116+
109117// ----------------------------------------------------------------------------
110118
111119inline std::unique_ptr<StackChunk> stack_chunk = nullptr ;
0 commit comments