Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit120e450

Browse files
authored
Merge pull request#1650 from zooba/issue-1648
Fixes#1648 Fix debug-attach and profiling for Python 3.6
2 parents60a2bac +881ec1e commit120e450

File tree

8 files changed

+167
-32
lines changed

8 files changed

+167
-32
lines changed

‎Python/Product/Core/Core.csproj‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@
7777
<Project>{89d51398-a003-44ba-b1b2-cfc6f8396d7e}</Project>
7878
<Name>Microsoft.PythonTools.BuildTasks</Name>
7979
</ProjectReference>
80+
<ProjectReferenceInclude="..\DebuggerHelper\DebuggerHelper.vcxproj">
81+
<Project>{25956dfa-17a2-4109-b9e5-d46cce1ed52f}</Project>
82+
<Name>DebuggerHelper</Name>
83+
</ProjectReference>
84+
<ProjectReferenceInclude="..\DebuggerHelper\DebuggerHelperX86.vcxproj">
85+
<Project>{a2a795f7-27d0-4801-88da-95b368f070ad}</Project>
86+
<Name>DebuggerHelperX86</Name>
87+
</ProjectReference>
8088
<ProjectReferenceInclude="..\Debugger\Debugger.csproj">
8189
<Project>{DECC7971-FA58-4DB0-9561-BFFADD393BBD}</Project>
8290
<Name>Microsoft.PythonTools.Debugger</Name>
@@ -93,6 +101,14 @@
93101
<Project>{3814d9db-10e6-4478-bd98-6c5840612af8}</Project>
94102
<Name>Microsoft.PythonTools.ProjectWizards</Name>
95103
</ProjectReference>
104+
<ProjectReferenceInclude="..\PyDebugAttach\PyDebugAttach.vcxproj">
105+
<Project>{ac19caa0-5c69-4b20-8a18-d4b6b65f22b8}</Project>
106+
<Name>PyDebugAttach</Name>
107+
</ProjectReference>
108+
<ProjectReferenceInclude="..\PyDebugAttach\PyDebugAttachX86.vcxproj">
109+
<Project>{70e7eb43-81d3-4aa0-9870-0b304732aff2}</Project>
110+
<Name>PyDebugAttachX86</Name>
111+
</ProjectReference>
96112
<ProjectReferenceInclude="..\PythonTools\PythonTools.csproj">
97113
<Project>{fa7be5f5-e04f-4613-b7ac-70ce10d1bb68}</Project>
98114
<Name>Microsoft.PythonTools</Name>

‎Python/Product/PyDebugAttach/PyDebugAttach.cpp‎

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,8 @@ long GetPythonThreadId(PythonVersion version, PyThreadState* curThread) {
722722
threadId = ((PyThreadState_25_27*)curThread)->thread_id;
723723
}elseif (PyThreadState_30_33::IsFor(version)) {
724724
threadId = ((PyThreadState_30_33*)curThread)->thread_id;
725-
}elseif (PyThreadState_34_35::IsFor(version)) {
726-
threadId = ((PyThreadState_34_35*)curThread)->thread_id;
725+
}elseif (PyThreadState_34_36::IsFor(version)) {
726+
threadId = ((PyThreadState_34_36*)curThread)->thread_id;
727727
}
728728
return threadId;
729729
}
@@ -855,17 +855,14 @@ bool DoAttach(HMODULE module, ConnectionInfo& connInfo, bool isDebug) {
855855
auto getThreadTls = (PyThread_get_key_value*)GetProcAddress(module,"PyThread_get_key_value");
856856
auto setThreadTls = (PyThread_set_key_value*)GetProcAddress(module,"PyThread_set_key_value");
857857
auto delThreadTls = (PyThread_delete_key_value*)GetProcAddress(module,"PyThread_delete_key_value");
858-
auto pyGilStateEnsure = (PyGILState_EnsureFunc*)GetProcAddress(module,"PyGILState_Ensure");
859-
auto pyGilStateRelease = (PyGILState_ReleaseFunc*)GetProcAddress(module,"PyGILState_Release");
860858
auto PyCFrame_Type = (PyTypeObject*)GetProcAddress(module,"PyCFrame_Type");
861859

862860
if (addPendingCall ==nullptr || curPythonThread ==nullptr || interpHead ==nullptr || gilEnsure ==nullptr || gilRelease ==nullptr || threadHead ==nullptr ||
863861
initThreads ==nullptr || releaseLock ==nullptr || threadsInited ==nullptr || threadNext ==nullptr || threadSwap ==nullptr ||
864862
pyDictNew ==nullptr || pyCompileString ==nullptr || pyEvalCode ==nullptr || getDictItem ==nullptr || call ==nullptr ||
865863
getBuiltins ==nullptr || dictSetItem ==nullptr || intFromLong ==nullptr || pyErrRestore ==nullptr || pyErrFetch ==nullptr ||
866864
errOccurred ==nullptr || pyImportMod ==nullptr || pyGetAttr ==nullptr || pyNone ==nullptr || pySetAttr ==nullptr || boolFromLong ==nullptr ||
867-
getThreadTls ==nullptr || setThreadTls ==nullptr || delThreadTls ==nullptr ||
868-
pyGilStateEnsure ==nullptr || pyGilStateRelease ==nullptr) {
865+
getThreadTls ==nullptr || setThreadTls ==nullptr || delThreadTls ==nullptr) {
869866
// we're missing some APIs, we cannot attach.
870867
connInfo.ReportError(ConnError_PythonNotFound);
871868
returnfalse;
@@ -975,13 +972,13 @@ bool DoAttach(HMODULE module, ConnectionInfo& connInfo, bool isDebug) {
975972
// Py_InitThreads to bring up multi-threading.
976973
// Some context here: http://bugs.python.org/issue11329
977974
// http://pytools.codeplex.com/workitem/834
978-
gilState =pyGilStateEnsure();
975+
gilState =gilEnsure();
979976
}
980977
initThreads();
981978

982979
if (version >= PythonVersion_32) {
983980
// we will release the GIL here
984-
pyGilStateRelease(gilState);
981+
gilRelease(gilState);
985982
}else {
986983
releaseLock();
987984
}
@@ -1149,8 +1146,8 @@ bool DoAttach(HMODULE module, ConnectionInfo& connInfo, bool isDebug) {
11491146
frame = ((PyThreadState_25_27*)curThread)->frame;
11501147
}elseif (PyThreadState_30_33::IsFor(version)) {
11511148
frame = ((PyThreadState_30_33*)curThread)->frame;
1152-
}elseif (PyThreadState_34_35::IsFor(version)) {
1153-
frame = ((PyThreadState_34_35*)curThread)->frame;
1149+
}elseif (PyThreadState_34_36::IsFor(version)) {
1150+
frame = ((PyThreadState_34_36*)curThread)->frame;
11541151
}
11551152

11561153
auto threadObj =PyObjectHolder(isDebug,call(new_thread.ToPython(), pyThreadId.ToPython(), pyTrue, frame,NULL));
@@ -1342,8 +1339,8 @@ int TraceGeneral(int interpreterId, PyObject *obj, PyFrameObject *frame, int wha
13421339
((PyThreadState_25_27*)curThread)->c_tracefunc(((PyThreadState_25_27*)curThread)->c_traceobj, frame, what, arg);
13431340
}elseif (PyThreadState_30_33::IsFor(version)) {
13441341
((PyThreadState_30_33*)curThread)->c_tracefunc(((PyThreadState_30_33*)curThread)->c_traceobj, frame, what, arg);
1345-
}elseif (PyThreadState_34_35::IsFor(version)) {
1346-
((PyThreadState_34_35*)curThread)->c_tracefunc(((PyThreadState_34_35*)curThread)->c_traceobj, frame, what, arg);
1342+
}elseif (PyThreadState_34_36::IsFor(version)) {
1343+
((PyThreadState_34_36*)curThread)->c_tracefunc(((PyThreadState_34_36*)curThread)->c_traceobj, frame, what, arg);
13471344
}
13481345
}
13491346
return0;
@@ -1387,8 +1384,8 @@ void SetInitialTraceFunc(DWORD interpreterId, PyThreadState *thread) {
13871384
gilstate_counter = ((PyThreadState_25_27*)thread)->gilstate_counter;
13881385
}elseif (PyThreadState_30_33::IsFor(version)) {
13891386
gilstate_counter = ((PyThreadState_30_33*)thread)->gilstate_counter;
1390-
}elseif (PyThreadState_34_35::IsFor(version)) {
1391-
gilstate_counter = ((PyThreadState_34_35*)thread)->gilstate_counter;
1387+
}elseif (PyThreadState_34_36::IsFor(version)) {
1388+
gilstate_counter = ((PyThreadState_34_36*)thread)->gilstate_counter;
13921389
}
13931390

13941391
if (gilstate_counter ==1) {

‎Python/Product/VsPyProf/PythonApi.cpp‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ VsPyProf* VsPyProf::Create(HMODULE pythonModule) {
8888
}
8989

9090
if ((major ==2 && (minor >=4 && minor <=7)) ||
91-
(major ==3 && (minor >=0 && minor <=5))) {
91+
(major ==3 && (minor >=0 && minor <=6))) {
9292
returnnewVsPyProf(pythonModule,
9393
major,
9494
minor,
@@ -134,6 +134,8 @@ bool VsPyProf::GetUserToken(PyFrameObject* frameObj, DWORD_PTR& func, DWORD_PTR&
134134
filename = ((PyCodeObject30_32*)codeObj)->co_filename;
135135
}elseif (PyCodeObject33_35::IsFor(MajorVersion, MinorVersion)) {
136136
filename = ((PyCodeObject33_35*)codeObj)->co_filename;
137+
}elseif (PyCodeObject36::IsFor(MajorVersion, MinorVersion)) {
138+
filename = ((PyCodeObject36*)codeObj)->co_filename;
137139
}
138140
module = (DWORD_PTR)filename;
139141

@@ -210,6 +212,9 @@ bool VsPyProf::GetUserToken(PyFrameObject* frameObj, DWORD_PTR& func, DWORD_PTR&
210212
}elseif (PyCodeObject33_35::IsFor(MajorVersion, MinorVersion)) {
211213
RegisterName(func, ((PyCodeObject33_35*)codeObj)->co_name, &moduleName);
212214
lineno = ((PyCodeObject33_35*)codeObj)->co_firstlineno;
215+
}elseif (PyCodeObject36::IsFor(MajorVersion, MinorVersion)) {
216+
RegisterName(func, ((PyCodeObject36*)codeObj)->co_name, &moduleName);
217+
lineno = ((PyCodeObject36*)codeObj)->co_firstlineno;
213218
}
214219

215220
// give the profiler the line number of this function
@@ -242,6 +247,9 @@ wstring VsPyProf::GetClassNameFromFrame(PyFrameObject* frameObj, PyObject *codeO
242247
}elseif (PyCodeObject33_35::IsFor(MajorVersion, MinorVersion)) {
243248
argCount = ((PyCodeObject33_35*)codeObj)->co_argcount;
244249
argNames = (PyTupleObject*)((PyCodeObject33_35*)codeObj)->co_varnames;
250+
}elseif (PyCodeObject36::IsFor(MajorVersion, MinorVersion)) {
251+
argCount = ((PyCodeObject36*)codeObj)->co_argcount;
252+
argNames = (PyTupleObject*)((PyCodeObject36*)codeObj)->co_varnames;
245253
}
246254

247255
if (argCount !=0 && argNames->ob_type == PyTuple_Type) {
@@ -252,8 +260,8 @@ wstring VsPyProf::GetClassNameFromFrame(PyFrameObject* frameObj, PyObject *codeO
252260
PyObject* self =nullptr;
253261
if (PyFrameObject25_33::IsFor(MajorVersion, MinorVersion)) {
254262
self = ((PyFrameObject25_33*)frameObj)->f_localsplus[0];
255-
}elseif (PyFrameObject34_35::IsFor(MajorVersion, MinorVersion)) {
256-
self = ((PyFrameObject34_35*)frameObj)->f_localsplus[0];
263+
}elseif (PyFrameObject34_36::IsFor(MajorVersion, MinorVersion)) {
264+
self = ((PyFrameObject34_36*)frameObj)->f_localsplus[0];
257265
}
258266
returnGetClassNameFromSelf(self, codeObj);
259267
}
@@ -281,6 +289,8 @@ wstring VsPyProf::GetClassNameFromSelf(PyObject* self, PyObject *codeObj) {
281289
nameObj = ((PyCodeObject30_32*)codeObj)->co_name;
282290
}elseif (PyCodeObject33_35::IsFor(MajorVersion, MinorVersion)) {
283291
nameObj = ((PyCodeObject33_35*)codeObj)->co_name;
292+
}elseif (PyCodeObject36::IsFor(MajorVersion, MinorVersion)) {
293+
nameObj = ((PyCodeObject36*)codeObj)->co_name;
284294
}
285295
GetNameAscii(nameObj, codeName);
286296

‎Python/Product/VsPyProf/python.h‎

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ enum PythonVersion {
2828
PythonVersion_32 =0x0302,
2929
PythonVersion_33 =0x0303,
3030
PythonVersion_34 =0x0304,
31-
PythonVersion_35 =0x0305
31+
PythonVersion_35 =0x0305,
32+
PythonVersion_36 =0x0306
3233
};
3334

3435

@@ -144,7 +145,38 @@ class PyCodeObject33_35 : public PyObject {
144145
}
145146
};
146147

147-
// 2.5 - 3.1
148+
// 3.6
149+
classPyCodeObject36 :publicPyObject {
150+
public:
151+
int co_argcount;/* #arguments, except *args*/
152+
int co_kwonlyargcount;/* #keyword only arguments*/
153+
int co_nlocals;/* #local variables*/
154+
int co_stacksize;/* #entries needed for evaluation stack*/
155+
int co_flags;/* CO_..., see below*/
156+
int co_firstlineno;/* first source line number*/
157+
PyObject *co_code;/* instruction opcodes*/
158+
PyObject *co_consts;/* list (constants used)*/
159+
PyObject *co_names;/* list of strings (names used)*/
160+
PyObject *co_varnames;/* tuple of strings (local variable names)*/
161+
PyObject *co_freevars;/* tuple of strings (free variable names)*/
162+
PyObject *co_cellvars;/* tuple of strings (cell variable names)*/
163+
/* The rest doesn't count for hash or comparisons*/
164+
unsignedchar *co_cell2arg;/* Maps cell vars which are arguments.*/
165+
PyObject *co_filename;/* unicode (where it was loaded from)*/
166+
PyObject *co_name;/* unicode (name, for reference)*/
167+
PyObject *co_lnotab;/* string (encoding addr<->lineno mapping)*/
168+
void *co_zombieframe;/* for optimization only (see frameobject.c)*/
169+
170+
staticboolIsFor(int majorVersion,int minorVersion) {
171+
return majorVersion ==3 && minorVersion >=6;
172+
}
173+
174+
staticboolIsFor(PythonVersion version) {
175+
return version >= PythonVersion_36;
176+
}
177+
};
178+
179+
// 2.5 - 3.6
148180
classPyFunctionObject :publicPyObject {
149181
public:
150182
PyObject *func_code;/* A code object*/
@@ -175,7 +207,7 @@ typedef struct {
175207
long hash;/* Hash value; -1 if not set*/
176208
} PyUnicodeObject;
177209

178-
// 2.4 - 3.5 compatible
210+
// 2.4 - 3.6 compatible
179211
classPyFrameObject :publicPyVarObject {
180212
public:
181213
PyFrameObject *f_back;/* previous frame, or NULL*/
@@ -216,7 +248,7 @@ class PyFrameObject25_33 : public PyFrameObject {
216248
}
217249
};
218250

219-
classPyFrameObject34_35 :publicPyFrameObject {
251+
classPyFrameObject34_36 :publicPyFrameObject {
220252
public:
221253
/* Borrowed reference to a generator, or NULL*/
222254
PyObject *f_gen;
@@ -231,14 +263,14 @@ class PyFrameObject34_35 : public PyFrameObject {
231263
PyObject *f_localsplus[1];/* locals+stack, dynamically sized*/
232264

233265
staticboolIsFor(int majorVersion,int minorVersion) {
234-
return majorVersion ==3 && minorVersion >=4 && minorVersion <=5;
266+
return majorVersion ==3 && minorVersion >=4 && minorVersion <=6;
235267
}
236268
};
237269

238270

239271
typedefvoid (*destructor)(PyObject *);
240272

241-
// 2.4 - 3.5
273+
// 2.4 - 3.6
242274
classPyMethodDef {
243275
public:
244276
char *ml_name;/* The name of the built-in function/method*/
@@ -261,7 +293,7 @@ class PyTypeObject : public PyVarObject {
261293
void* tp_setattr;
262294
union {
263295
void* tp_compare;/* 2.4 - 3.4*/
264-
void* tp_as_async;/* 3.5*/
296+
void* tp_as_async;/* 3.5- 3.6*/
265297
};
266298
void* tp_repr;
267299

@@ -331,7 +363,7 @@ class PyTypeObject : public PyVarObject {
331363
unsignedint tp_version_tag;
332364
};
333365

334-
// 2.4 - 3.5
366+
// 2.4 - 3.6
335367
classPyTupleObject :publicPyVarObject {
336368
public:
337369
PyObject *ob_item[1];
@@ -342,7 +374,7 @@ class PyTupleObject : public PyVarObject {
342374
*/
343375
};
344376

345-
// 2.4 - 3.5
377+
// 2.4 - 3.6
346378
classPyCFunctionObject :publicPyObject {
347379
public:
348380
PyMethodDef *m_ml;/* Description of the C function to call*/
@@ -473,7 +505,7 @@ class PyThreadState_30_33 : public PyThreadState {
473505
}
474506
};
475507

476-
classPyThreadState_34_35 :publicPyThreadState {
508+
classPyThreadState_34_36 :publicPyThreadState {
477509
public:
478510
PyThreadState *prev;
479511
PyThreadState *next;
@@ -513,11 +545,11 @@ class PyThreadState_34_35 : public PyThreadState {
513545

514546
/* XXX signal handlers should also be here*/
515547
staticboolIsFor(int majorVersion,int minorVersion) {
516-
return majorVersion ==3 && minorVersion >=4 && minorVersion <=5;
548+
return majorVersion ==3 && minorVersion >=4 && minorVersion <=6;
517549
}
518550

519551
staticboolIsFor(PythonVersion version) {
520-
return version >= PythonVersion_34 && version <=PythonVersion_35;
552+
return version >= PythonVersion_34 && version <=PythonVersion_36;
521553
}
522554
};
523555

@@ -570,6 +602,7 @@ static PythonVersion GetPythonVersion(HMODULE hMod) {
570602
case'3':return PythonVersion_33;
571603
case'4':return PythonVersion_34;
572604
case'5':return PythonVersion_35;
605+
case'6':return PythonVersion_36;
573606
}
574607
}
575608
}

‎Python/Tests/Core/DebugReplEvaluatorTests.cs‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public void ErrorInInput() {
116116
Assert.AreEqual(@"Traceback (most recent call last):
117117
File ""<debug input>"", line 1, in <module>
118118
NameError: name 'does_not_exist' is not defined
119-
",_window.Error);
119+
".Replace("\r\n","\n"),_window.Error.Replace("\r\n","\n"));
120120
}
121121

122122
[TestMethod,Priority(3)]
@@ -434,6 +434,21 @@ internal override PythonVersion Version {
434434
}
435435
}
436436

437+
[TestClass]
438+
publicclassDebugReplEvaluatorTests36:DebugReplEvaluatorTests{
439+
[ClassInitialize]
440+
publicstaticnewvoidDoDeployment(TestContextcontext){
441+
AssertListener.Initialize();
442+
PythonTestData.Deploy();
443+
}
444+
445+
internaloverridePythonVersionVersion{
446+
get{
447+
returnPythonPaths.Python36??PythonPaths.Python36_x64;
448+
}
449+
}
450+
}
451+
437452
[TestClass]
438453
publicclassDebugReplEvaluatorTests27:DebugReplEvaluatorTests{
439454
[ClassInitialize]

‎Python/Tests/DebuggerTests/AttachTests.cs‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,10 @@ public void AttachPtvsd() {
807807
stringscript=TestData.GetPath(@"TestData\DebuggerProject\AttachPtvsd.py");
808808
varpsi=newProcessStartInfo(Version.InterpreterPath,PtvsdInterpreterArguments+"\""+script+"\""){
809809
WorkingDirectory=TestData.GetPath(),
810-
UseShellExecute=false
810+
UseShellExecute=false,
811+
RedirectStandardOutput=true,
812+
RedirectStandardError=true,
813+
CreateNoWindow=true
811814
};
812815

813816
varp=Process.Start(psi);
@@ -822,7 +825,7 @@ public void AttachPtvsd() {
822825
break;
823826
}catch(SocketException){
824827
// Failed to connect - the process might have not started yet, so keep trying a few more times.
825-
if(i>=5){
828+
if(i>=5||p.HasExited){
826829
throw;
827830
}
828831
}
@@ -862,6 +865,8 @@ public void AttachPtvsd() {
862865
DetachProcess(proc);
863866
}
864867
}finally{
868+
Console.WriteLine(p.StandardOutput.ReadToEnd());
869+
Console.WriteLine(p.StandardError.ReadToEnd());
865870
DisposeProcess(p);
866871
}
867872
}
@@ -1046,6 +1051,28 @@ internal override PythonVersion Version {
10461051
}
10471052
}
10481053

1054+
[TestClass]
1055+
publicclassAttachTests36:AttachTests{
1056+
internaloverridePythonVersionVersion{
1057+
get{
1058+
returnPythonPaths.Python36;
1059+
}
1060+
}
1061+
1062+
publicoverridevoidAttachNewThread_PyThreadState_New(){
1063+
// PyEval_AcquireLock deprecated in 3.2
1064+
}
1065+
}
1066+
1067+
[TestClass]
1068+
publicclassAttachTests36_x64:AttachTests35{
1069+
internaloverridePythonVersionVersion{
1070+
get{
1071+
returnPythonPaths.Python36_x64;
1072+
}
1073+
}
1074+
}
1075+
10491076
[TestClass]
10501077
publicclassAttachTests25:AttachTests{
10511078
internaloverridePythonVersionVersion{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp