Skip to content

Commit c65b6ed

Browse files
committed
Linux GDB fixes
1 parent 224cd1e commit c65b6ed

4 files changed

Lines changed: 78 additions & 64 deletions

File tree

BeefySysLib/platform/posix/PosixCommon.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,10 @@ BFP_EXPORT BfpSpawn* BFP_CALLTYPE BfpSpawn_Create(const char* inTargetPath, cons
15031503
else
15041504
result = execv(targetPath.c_str(), (char* const*)&argvArr[0]);
15051505

1506+
close(STDOUT_FILENO);
1507+
close(STDERR_FILENO);
1508+
close(STDIN_FILENO);
1509+
15061510
BFP_ERRPRINTF("Couldn't execute %s\n", targetPath.c_str());
15071511

15081512
exit(-1);
@@ -3069,12 +3073,12 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_GetFullPath(const char* inPath, char* outPa
30693073

30703074
if (inPath[0] == '/')
30713075
{
3072-
str = inPath;
3076+
str = GetAbsPath(inPath, "/");
30733077
}
30743078
else
30753079
{
30763080
char* cwdPtr = getcwd(NULL, 0);
3077-
Beefy::String cwdPath = cwdPtr;
3081+
Beefy::String cwdPath = cwdPtr;
30783082
free(cwdPtr);
30793083
str = GetAbsPath(inPath, cwdPath);
30803084
}
@@ -3174,7 +3178,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_GetActualPath(const char* inPathC, char* ou
31743178
String parentPath;
31753179
String componentName;
31763180
int32 lastSep = subName.LastIndexOf(DIR_SEP_CHAR);
3177-
3181+
31783182
if (lastSep != -1)
31793183
{
31803184
parentPath = subName.Substring(0, lastSep);
@@ -3195,7 +3199,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_GetActualPath(const char* inPathC, char* ou
31953199
struct dirent* entry = NULL;
31963200
while ((entry = readdir(dir)) != NULL)
31973201
{
3198-
// Linux is case-sensitive, but we do a case-insensitive comparison
3202+
// Linux is case-sensitive, but we do a case-insensitive comparison
31993203
// to help find the correct case for the file
32003204
if (strcasecmp(entry->d_name, componentName.c_str()) == 0)
32013205
{

IDEHelper/DebugManager.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ DebugManager::~DebugManager()
110110
delete mNetManager;
111111
delete mDebuggerGDB;
112112
delete mDebugger64;
113-
delete mDebugger32;
113+
delete mDebugger32;
114114
/*for (auto stepFilter : mStepFilters)
115115
{
116116
}*/
@@ -761,11 +761,11 @@ BF_EXPORT int BF_CALLTYPE Debugger_GetAddrSize()
761761
BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* launchPath, const char* targetPath, const char* args, const char* workingDir, void* envBlockPtr, int envBlockSize, bool hotSwapEnabled, DbgOpenFileFlags openFileFlags)
762762
{
763763
BF_ASSERT(gDebugger == NULL);
764-
764+
765765
DebuggerResult debuggerResult = DebuggerResult_Ok;
766766

767767
if ((strstr(launchPath, "@gdb") != NULL) || (strstr(launchPath, "gdb:") != NULL))
768-
{
768+
{
769769
gDebugger = gDebugManager->mDebuggerGDB;
770770
}
771771
else
@@ -1321,9 +1321,8 @@ BF_EXPORT StringView BF_CALLTYPE Debugger_Evaluate(const char* expr, int callSta
13211321

13221322
String& outString = *gTLStrReturn.Get();
13231323
outString.clear();
1324-
#ifdef BF_PLATFORM_WINDOWS
1325-
outString = debugger->Evaluate(expr, callStackIdx, cursorPos, language, (DwEvalExpressionFlags)expressionFlags);
1326-
#endif
1324+
if (debugger != NULL)
1325+
outString = debugger->Evaluate(expr, callStackIdx, cursorPos, language, (DwEvalExpressionFlags)expressionFlags);
13271326
#ifdef BF_WANTS_LOG_DBG
13281327
{
13291328
int crPos = (int)outString.IndexOf('\n');

IDEHelper/GDBDebugger.cpp

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
#ifdef __linux__
99
#include <limits.h>
1010
#include <unistd.h>
11-
#ifndef MAX_PATH
12-
#define MAX_PATH PATH_MAX
13-
#endif
1411
#endif
1512
#ifdef __APPLE__
1613
#include <mach/mach.h>
1714
#endif
1815

16+
#ifndef MAX_PATH
17+
#define MAX_PATH PATH_MAX
18+
#endif
19+
1920
#include <cstdlib>
2021
#include <cstring>
2122
#include <cstdio>
@@ -379,7 +380,7 @@ GDBDebugger::GDBDebugger(DebugManager* debugManager)
379380
mLaunchMode = GDBLaunchMode_Local;
380381
mGDBReady = false;
381382
mRunning = false;
382-
mNeedsExecRun = false;
383+
mNeedsExecRun = false;
383384
}
384385

385386
GDBDebugger::~GDBDebugger()
@@ -542,7 +543,7 @@ void GDBDebugger::ReadStdout()
542543
mIncomingRecords.push_back(rec);
543544
}
544545
}
545-
}
546+
}
546547
}
547548

548549
//----------------------------------------------------------------------------
@@ -575,7 +576,7 @@ void GDBDebugger::ProcessRecord(GDBMIRecord* rec)
575576
OutputMessage(rec->mClass);
576577
}
577578
else if (rec->mType == GDBMIRecordType::LogStream)
578-
{
579+
{
579580
if (rec->mClass.StartsWith("Python Exception"))
580581
OutputRawMessage("errorsoft " + Trim(rec->mClass));
581582
else
@@ -784,12 +785,8 @@ void GDBDebugger::OpenFile(const StringImpl& launchPath, const StringImpl& targe
784785
mLaunchMode = GDBLaunchMode_GDBServer;
785786
mGDBServerHost = location + 4;
786787
}
787-
// else: unknown tag — ignore and treat the whole string as the path
788788

789-
if (mLaunchMode != GDBLaunchMode_Local)
790-
mLaunchPath = String(rawPath, (int)(atSign - rawPath));
791-
else
792-
mLaunchPath = launchPath;
789+
mLaunchPath = String(rawPath, (int)(atSign - rawPath));
793790
}
794791
else
795792
{
@@ -849,14 +846,23 @@ void GDBDebugger::DoLaunch()
849846
workingDirForGDB = ConvertToWSLPath(mWorkingDir);
850847
}
851848

849+
GDBLog("Launching GDB with exe='%s' args='%s'\n", gdbExe.c_str(), gdbBaseArgs.c_str());
850+
851+
BfpSpawnFlags spawnFlags = (BfpSpawnFlags)(
852+
BfpSpawnFlag_RedirectStdInput | BfpSpawnFlag_RedirectStdOutput |
853+
BfpSpawnFlag_RedirectStdError | BfpSpawnFlag_NoWindow);
854+
855+
#ifndef BF_PLATFORM_WINDOWS
856+
spawnFlags = (BfpSpawnFlags)(spawnFlags | BfpSpawnFlag_UseShellExecute);
857+
#endif
858+
852859
BfpSpawnResult spawnResult = BfpSpawnResult_Ok;
853860
BfpSpawn* spawn = BfpSpawn_Create(
854861
gdbExe.c_str(),
855862
gdbBaseArgs.c_str(),
856-
mWorkingDir.IsEmpty() ? NULL : mWorkingDir.c_str(),
863+
NULL, //mWorkingDir.IsEmpty() ? NULL : mWorkingDir.c_str(),
857864
NULL,
858-
(BfpSpawnFlags)(BfpSpawnFlag_RedirectStdInput | BfpSpawnFlag_RedirectStdOutput |
859-
BfpSpawnFlag_RedirectStdError | BfpSpawnFlag_NoWindow),
865+
spawnFlags,
860866
&spawnResult);
861867

862868
if ((spawn == NULL) || (spawnResult != BfpSpawnResult_Ok))
@@ -867,12 +873,6 @@ void GDBDebugger::DoLaunch()
867873
return;
868874
}
869875

870-
{
871-
AutoCrit autoCrit(mDebugManager->mCritSect);
872-
mGDBSpawn = spawn;
873-
mProcessId = BfpSpawn_GetProcessId(spawn);
874-
}
875-
876876
// Get stdin/stdout handles
877877
BfpFile* gdbStdin = NULL;
878878
BfpFile* gdbStdout = NULL;
@@ -881,6 +881,8 @@ void GDBDebugger::DoLaunch()
881881

882882
{
883883
AutoCrit autoCrit(mDebugManager->mCritSect);
884+
mGDBSpawn = spawn;
885+
mProcessId = BfpSpawn_GetProcessId(spawn);
884886
mGDBStdin = gdbStdin;
885887
mGDBStdout = gdbStdout;
886888
mGDBStderr = gdbStderr;
@@ -912,11 +914,18 @@ void GDBDebugger::DoLaunch()
912914
break;
913915
BfpThread_Sleep(5);
914916
waited += 5;
917+
918+
if (BfpThread_WaitFor(mStdoutThread, 0))
919+
{
920+
GDBLog("GDB process exited while waiting for prompt\n");
921+
break;
922+
}
915923
}
916924

917925
if (!gotPrompt)
918926
{
919-
OutputMessage("GDB: Timed out waiting for GDB prompt\n");
927+
GDBLog("Timed out waiting for GDB prompt\n");
928+
OutputMessage("error GDB failed to launch\n");
920929
AutoCrit autoCrit(mDebugManager->mCritSect);
921930
mRunState = RunState_Terminated;
922931
return;
@@ -956,7 +965,7 @@ void GDBDebugger::DoLaunch()
956965

957966
SendSyncNoResult("-interpreter-exec console \"set pagination off\"");
958967
SendSyncNoResult("-interpreter-exec console \"set debuginfod enabled on\"");
959-
SendSyncNoResult("-gdb-set auto-solib-add on");
968+
SendSyncNoResult("-gdb-set auto-solib-add on");
960969
SendSyncNoResult("-enable-pretty-printing");
961970

962971
// Set working directory if specified (WSL and SSH use the converted/remote path)
@@ -1095,7 +1104,7 @@ void GDBDebugger::DoLaunch()
10951104
}
10961105

10971106
AutoCrit autoCrit(mDebugManager->mCritSect);
1098-
CheckBreakpoints(true);
1107+
CheckBreakpoints(true);
10991108
mNeedsExecRun = true;
11001109
}
11011110

@@ -1378,7 +1387,7 @@ GDBMIRecord* GDBDebugger::InsertBreakpointByLocation(const char* file, int lineN
13781387
}
13791388

13801389
GDBMIRecord* GDBDebugger::InsertBreakpointByName(const char* sym, bool mainModuleOnly)
1381-
{
1390+
{
13821391
String cmd = StrFormat("-break-insert \"%s\"", sym);
13831392
return SendSync(cmd.c_str());
13841393
}
@@ -1731,7 +1740,7 @@ void GDBDebugger::UpdateCallStack(bool slowEarlyOut)
17311740
frame.mFile = ConvertFromWSLPath(frame.mFile);
17321741
frame.mFullFile = ConvertFromWSLPath(frame.mFullFile);
17331742
}
1734-
1743+
17351744
String lineStr = f->GetStr("line");
17361745
if (!lineStr.IsEmpty())
17371746
{
@@ -1741,7 +1750,7 @@ void GDBDebugger::UpdateCallStack(bool slowEarlyOut)
17411750
}
17421751

17431752
String func = f->GetStr("func");
1744-
1753+
17451754
// Check if this looks like a Beef frame (bf:: prefix)
17461755
frame.mIsBeef = (strncmp(func.c_str(), "bf::", 4) == 0) ||
17471756
StringView(frame.mFullFile).EndsWith(".bf", StringView::CompareKind_OrdinalIgnoreCase);
@@ -2405,13 +2414,13 @@ String GDBDebugger::Evaluate(const StringImpl& expr, int callStackIdx, int curso
24052414
(!isPointer));
24062415

24072416
String result;
2408-
2417+
24092418
result += displayVal;
24102419
if (pass == 1)
24112420
result += StrFormat(" @ 0x%@", ptrAddr);
24122421
result += '\n';
24132422
result += typeName;
2414-
2423+
24152424
if (pass == 1)
24162425
result += "*";
24172426

@@ -2526,7 +2535,7 @@ String GDBDebugger::Evaluate(const StringImpl& expr, int callStackIdx, int curso
25262535
{
25272536
result += '\n';
25282537
result += childExp;
2529-
result += '\t';
2538+
result += '\t';
25302539
result += collPtrValue;
25312540
result += childExp;
25322541
continue;
@@ -2542,20 +2551,20 @@ String GDBDebugger::Evaluate(const StringImpl& expr, int callStackIdx, int curso
25422551
result += StrFormat("({0}).%s", childExp.c_str());
25432552

25442553
bool useChildValue = !childType.EndsWith("*");
2545-
2554+
25462555
if ((childExp == "[Ptr]") && (childValuePtr != NULL))
25472556
{
25482557
collPtrValue = "((" + childType + ")" + *childValuePtr + ")";
25492558
useChildValue = true;
25502559
}
2551-
2560+
25522561
if ((childValuePtr != NULL) && (useChildValue))
25532562
{
25542563
result += '\t';
25552564
result += *childValuePtr;
25562565
result += '\t';
25572566
result += childType;
2558-
}
2567+
}
25592568
}
25602569
}
25612570
}
@@ -2700,7 +2709,7 @@ void GDBDebugger::StopDebugging()
27002709
mActiveBreakpoint = NULL;
27012710

27022711
if (mGDBSpawn != NULL)
2703-
{
2712+
{
27042713
// Ask GDB to quit gracefully
27052714
if (mGDBStdin != NULL)
27062715
SendSync("-gdb-exit", 2000);
@@ -2810,7 +2819,7 @@ void GDBDebugger::Detach()
28102819
GDBMIRecord* rec = SendSync("-target-detach");
28112820
delete rec;
28122821
}
2813-
2822+
28142823
GDBMIRecord* rec = SendSync("-gdb-exit", 2000);
28152824
delete rec;
28162825

@@ -2873,7 +2882,7 @@ void GDBDebugger::Detach()
28732882
mGDBServerHost = "";
28742883
mGDBReady = false;
28752884
mRunning = false;
2876-
mNeedsExecRun = false;
2885+
mNeedsExecRun = false;
28772886
}
28782887

28792888
//----------------------------------------------------------------------------

0 commit comments

Comments
 (0)