Skip to content

Commit b942785

Browse files
committed
Set fromC appropriately. Fixes #7844
1 parent 428ade7 commit b942785

File tree

3 files changed

+46
-27
lines changed

3 files changed

+46
-27
lines changed

src/debuginfo.cpp

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,13 @@ const char *jl_demangle(const char *name)
162162

163163
JuliaJITEventListener *jl_jit_events;
164164

165-
extern "C" void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, uintptr_t pointer, int skipC);
165+
extern "C" void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, uintptr_t pointer, int *fromC, int skipC);
166166

167-
void lookup_pointer(DIContext *context, const char **name, size_t *line, const char **filename, size_t pointer, int demangle)
167+
void lookup_pointer(DIContext *context, const char **name, size_t *line, const char **filename, size_t pointer, int demangle, int *fromC)
168168
{
169+
DILineInfo info;
169170
if (demangle && *name != NULL)
170171
*name = jl_demangle(*name);
171-
if (context == NULL) return;
172172
#ifdef LLVM35
173173
DILineInfoSpecifier infoSpec(DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
174174
DILineInfoSpecifier::FunctionNameKind::ShortName);
@@ -177,21 +177,26 @@ void lookup_pointer(DIContext *context, const char **name, size_t *line, const c
177177
DILineInfoSpecifier::AbsoluteFilePath |
178178
DILineInfoSpecifier::FunctionName;
179179
#endif
180-
DILineInfo info = context->getLineInfoForAddress(pointer, infoSpec);
180+
if (context == NULL) goto done;
181+
info = context->getLineInfoForAddress(pointer, infoSpec);
181182
#ifndef LLVM35 // LLVM <= 3.4
182-
if (strcmp(info.getFunctionName(), "<invalid>") == 0) return;
183+
if (strcmp(info.getFunctionName(), "<invalid>") == 0) goto done;
183184
if (demangle)
184-
*name = jl_demangle(info.getFunctionName());
185+
*name = jl_demangle(info.getFunctionName());
185186
else
186-
*name = strdup(info.getFunctionName());
187+
*name = strdup(info.getFunctionName());
187188
*line = info.getLine();
188189
*filename = strdup(info.getFileName());
189190
#else
190-
if (strcmp(info.FunctionName.c_str(), "<invalid>") == 0) return;
191+
if (strcmp(info.FunctionName.c_str(), "<invalid>") == 0) goto done;
191192
*name = strdup(info.FunctionName.c_str());
192193
*line = info.Line;
193194
*filename = strdup(info.FileName.c_str());
194195
#endif
196+
done:
197+
// If this is a jlcall wrapper, set fromC to match JIT behavior
198+
if (*name != NULL && memcmp(*name,"jlcall_",7) == 0)
199+
*fromC = true;
195200
}
196201

197202
#ifdef _OS_DARWIN_
@@ -254,12 +259,12 @@ bool jl_is_sysimg(const char *path)
254259
}
255260

256261
#if defined(_OS_WINDOWS_) && !defined(USE_MCJIT)
257-
void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int skipC)
262+
void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC)
258263
{
259264
return;
260265
}
261266
#else
262-
void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int skipC)
267+
void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC)
263268
{
264269
#ifdef _OS_WINDOWS_
265270
DWORD fbase = SymGetModuleBase64(GetCurrentProcess(),(DWORD)pointer);
@@ -269,7 +274,8 @@ void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filen
269274
Dl_info dlinfo;
270275
const char *fname = 0;
271276
if ((dladdr((void*)pointer, &dlinfo) != 0) && dlinfo.dli_fname) {
272-
if (skipC && !jl_is_sysimg(dlinfo.dli_fname))
277+
*fromC = !jl_is_sysimg(dlinfo.dli_fname);
278+
if (skipC && *fromC)
273279
return;
274280
// In case we fail with the debug info lookup, we at least still
275281
// have the function name, even if we don't have line numbers
@@ -288,7 +294,9 @@ void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filen
288294
ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
289295
SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)pointer, &ModuleInfo);
290296
fname = ModuleInfo.LoadedImageName;
291-
JL_PRINTF(JL_STDOUT,fname);
297+
*fromC = !jl_is_sysimg(fname);
298+
if (skipC && *fromC)
299+
return;
292300
#endif
293301
if (it == objfilemap.end()) {
294302
#ifdef _OS_DARWIN_
@@ -310,7 +318,7 @@ void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filen
310318
if (!origerrorobj) {
311319
objfileentry_t entry = {obj,context,slide};
312320
objfilemap[fbase] = entry;
313-
return;
321+
goto lookup;
314322
}
315323
#ifdef LLVM36
316324
llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get().release();
@@ -322,7 +330,7 @@ void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filen
322330
if (!getObjUUID(morigobj,uuid)) {
323331
objfileentry_t entry = {obj,context,slide};
324332
objfilemap[fbase] = entry;
325-
return;
333+
goto lookup;
326334
}
327335

328336
// On OS X debug symbols are not contained in the dynamic library and that's why
@@ -399,51 +407,61 @@ void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filen
399407
context = it->second.ctx;
400408
slide = it->second.slide;
401409
}
402-
lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(fname));
410+
lookup:
411+
lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(fname), fromC);
412+
return;
403413
}
414+
*fromC = 1;
404415
return;
405416
}
406417
#endif
407418

408-
void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int skipC)
419+
void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC)
409420
{
410421
*name = NULL;
411422
*line = -1;
412423
*filename = "no file";
424+
*fromC = 0;
413425

414426
#if USE_MCJIT
415427
// With MCJIT we can get function information directly from the ObjectFile
416428
std::map<size_t, ObjectInfo, revcomp> &objmap = jl_jit_events->getObjectMap();
417429
std::map<size_t, ObjectInfo, revcomp>::iterator it = objmap.lower_bound(pointer);
418430

419431
if (it == objmap.end())
420-
return jl_getDylibFunctionInfo(name,line,filename,pointer,skipC);
432+
return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
421433
if ((pointer - it->first) > it->second.size)
422-
return jl_getDylibFunctionInfo(name,line,filename,pointer,skipC);
434+
return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
423435

424436
#ifdef LLVM36
425437
DIContext *context = DIContext::getDWARFContext(*it->second.object);
426438
#else
427439
DIContext *context = DIContext::getDWARFContext(it->second.object);
428440
#endif
429-
lookup_pointer(context, name, line, filename, pointer, 1);
441+
lookup_pointer(context, name, line, filename, pointer, 1, fromC);
430442

431443
#else // !USE_MCJIT
432444

433445
// Without MCJIT we use the FuncInfo structure containing address maps
434446
std::map<size_t, FuncInfo, revcomp> &info = jl_jit_events->getMap();
435447
std::map<size_t, FuncInfo, revcomp>::iterator it = info.lower_bound(pointer);
436448
if (it != info.end() && (size_t)(*it).first + (*it).second.lengthAdr >= pointer) {
437-
// We do this to hide the jlcall wrappers when getting julia, but
438-
// it is still good to have them for regular lookup of C frames.
439-
if (skipC && (*it).second.lines.empty())
449+
// We do this to hide the jlcall wrappers when getting julia backtraces,
450+
// but it is still good to have them for regular lookup of C frames.
451+
if (skipC && (*it).second.lines.empty()) {
452+
// Technically not true, but we don't want them
453+
// in julia backtraces, so close enough
454+
*fromC = 1;
440455
return;
456+
}
441457

442458
*name = (*it).second.name.c_str();
443459
*filename = (*it).second.filename.c_str();
444460

445-
if ((*it).second.lines.empty())
461+
if ((*it).second.lines.empty()) {
462+
*fromC = 1;
446463
return;
464+
}
447465

448466
std::vector<JITEvent_EmittedFunctionDetails::LineStart>::iterator vit =
449467
(*it).second.lines.begin();
@@ -473,7 +491,7 @@ void jl_getFunctionInfo(const char **name, size_t *line, const char **filename,
473491
}
474492
}
475493
else {
476-
jl_getDylibFunctionInfo(name,line,filename,pointer,skipC);
494+
jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
477495
}
478496
#endif // USE_MCJIT
479497
}

src/task.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -456,17 +456,17 @@ static void init_task(jl_task_t *t)
456456
ptrint_t bt_data[MAX_BT_SIZE+1];
457457
size_t bt_size = 0;
458458

459-
void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int skipC);
459+
void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC);
460460

461461
static const char *name_unknown = "???";
462462
static int frame_info_from_ip(const char **func_name, size_t *line_num, const char **file_name, size_t ip, int skipC)
463463
{
464464
int fromC = 0;
465465

466-
jl_getFunctionInfo(func_name, line_num, file_name, ip, skipC);
466+
jl_getFunctionInfo(func_name, line_num, file_name, ip, &fromC, skipC);
467467
if (*func_name == NULL) {
468-
fromC = 1;
469468
#if defined(_OS_WINDOWS_)
469+
fromC = 1;
470470
if (jl_in_stackwalk) {
471471
*func_name = name_unknown;
472472
*file_name = name_unknown;

test/backtrace.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ have_backtrace = false
33
for l in bt
44
lkup = ccall(:jl_lookup_code_address, Any, (Ptr{Void},), l)
55
if lkup[1] == :backtrace
6+
@test lkup[4] == false # fromC
67
have_backtrace = true
78
break
89
end

0 commit comments

Comments
 (0)