Skip to content

Refactor source location interface #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions lib/runtime/RuntimeInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ typedef struct typeart_type_info_t {
typeart_base_type_info base_type_info; // API dependent
} typeart_type_info;

typedef struct typeart_source_loc_t {
char* file;
char* function;
unsigned line;
} typeart_source_location;

/**
* Determines the type and array element count at the given address.
* For nested types with classes/structs, the containing type is resolved recursively, until an exact with the address
Expand Down Expand Up @@ -194,16 +200,25 @@ typeart_status typeart_get_return_address(const void* addr, const void** return_
* caller.
*
* \param[in] addr The address.
* \param[out] file The file where the address was created at.
* \param[out] function The function where the address was created at.
* \param[out] line The approximate line where the address was created at.
* \param[out] source_loc The file/function/line where the address was created at.
*
* \return One of the following status codes:
* - TYPEART_OK: Success.
* - TYPEART_UNKNOWN_ADDRESS: The given address is either not allocated, or was not recorded by the runtime.
* - TYPEART_ERROR: Memory could not be allocated.
*/
typeart_status typeart_get_source_location(const void* addr, char** file, char** function, char** line);
typeart_status typeart_get_source_location(const void* addr, typeart_source_location* source_loc);

/**
* Free previously allocated typeart_source_location.
*
* \param[in] source_loc The file/function/line where the address was created at.
*
* \return One of the following status codes:
* - TYPEART_OK: Success.
* - TYPEART_ERROR: source_loc was NULL.
*/
typeart_status typeart_free_source_location(typeart_source_location* source_loc);

/**
* Given a type ID, this function provides information about the corresponding struct type.
Expand Down
56 changes: 49 additions & 7 deletions lib/runtime/TypeResolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "llvm/Support/raw_ostream.h"

#include <cassert>
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <utility>
Expand Down Expand Up @@ -331,15 +332,15 @@ inline typeart_status query_struct_layout(int type_id, typeart_struct_layout* st
}

char* string2char(std::string_view src) {
const void* ret_addr = __builtin_return_address(0);
// const void* ret_addr = __builtin_return_address(0);
const size_t source_length = src.size() + 1; // +1 for '\0'
char* string_copy = (char*)malloc(sizeof(char) * source_length);

if (string_copy == nullptr) {
return nullptr;
}

typeart::RuntimeSystem::get().allocTracker.onAlloc(string_copy, TYPEART_CHAR_8, source_length, ret_addr);
// typeart::RuntimeSystem::get().allocTracker.onAlloc(string_copy, TYPEART_CHAR_8, source_length, ret_addr);

memcpy(string_copy, src.data(), source_length);

Expand Down Expand Up @@ -398,18 +399,41 @@ typeart_status typeart_get_return_address(const void* addr, const void** return_
return TYPEART_UNKNOWN_ADDRESS;
}

typeart_status_t typeart_get_source_location(const void* addr, char** file, char** function, char** line) {
// typeart_status_t typeart_get_source_location(const void* addr, char** file, char** function, char** line) {
// using namespace typeart::detail;
// typeart::RTGuard guard;

// auto source_loc = typeart::SourceLocation::create(addr);

// if (source_loc) {
// *file = string2char(source_loc->file);
// *function = string2char(source_loc->function);
// *line = string2char(source_loc->line);

// if (*file == nullptr || *function == nullptr || *line == nullptr) {
// return TYPEART_ERROR;
// }

// return TYPEART_OK;
// }

// return TYPEART_UNKNOWN_ADDRESS;
// }

typeart_status_t typeart_get_source_location(const void* addr, typeart_source_location* source_location) {
using namespace typeart::detail;
typeart::RTGuard guard;

auto source_loc = typeart::SourceLocation::create(addr);

if (source_loc) {
*file = string2char(source_loc->file);
*function = string2char(source_loc->function);
*line = string2char(source_loc->line);
source_location->file = string2char(source_loc->file);
source_location->function = string2char(source_loc->function);
source_location->line = 0;
const auto& line = source_loc->line;
auto [ptr, ec] = std::from_chars(line.data(), line.data() + line.size(), source_location->line);

if (*file == nullptr || *function == nullptr || *line == nullptr) {
if (source_location->file == nullptr || source_location->function == nullptr || ec != std::errc{}) {
return TYPEART_ERROR;
}

Expand All @@ -419,6 +443,24 @@ typeart_status_t typeart_get_source_location(const void* addr, char** file, char
return TYPEART_UNKNOWN_ADDRESS;
}

typeart_status_t typeart_free_source_location(typeart_source_location* source_location) {
using namespace typeart::detail;
typeart::RTGuard guard;

if (source_location == nullptr) {
return TYPEART_ERROR;
}

free(source_location->file);
free(source_location->function);

source_location->file = nullptr;
source_location->function = nullptr;
source_location->line = 0;

return TYPEART_OK;
}

const char* typeart_get_type_name(int type_id) {
typeart::RTGuard guard;
return typeart::RuntimeSystem::get().typeResolution.db().getTypeName(type_id).c_str();
Expand Down
27 changes: 10 additions & 17 deletions test/runtime/46_source_location.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,22 @@ int main(int argc, char** argv) {
return 1;
}

char* file;
char* func;
char* line;

if (typeart_get_source_location(addr, &file, &func, &line) != TYPEART_OK) {
typeart_source_location location;
if (typeart_get_source_location(addr, &location) != TYPEART_OK) {
fprintf(stderr, "Error getting source loc\n");
return -1;
}

fprintf(stderr, "Loc File: %s\n", file);
fprintf(stderr, "Loc Function: %s\n", func);
fprintf(stderr, "Loc Line: %s\n", line);
fprintf(stderr, "Loc File: %s\n", location.file);
fprintf(stderr, "Loc Function: %s\n", location.function);
fprintf(stderr, "Loc Line: %i\n", location.line);

check_addr(file);
check_addr(func);
check_addr(line);
typeart_free_source_location(&location);

free(file);
free(line);
free(func);
if (location.file != NULL || location.function != NULL) {
fprintf(stderr, "Error free'ing source loc\n");
return -1;
}

return 0;
}
Expand All @@ -66,6 +62,3 @@ int main(int argc, char** argv) {
// CHECK: Loc File:{{.*}}46_source_location.c
// CHECK: Loc Function: main
// CHECK: Loc Line: 3{{(3|5)}}
// CHECK: Address check OK
// CHECK: Address check OK
// CHECK: Address check OK